archive.org 站点上动态创建的 "a"(锚点)元素的 href 错误

Wrong href of dynamically created "a" (anchor) element on archive.org site

我使用此代码创建“a”元素以将其添加到页面。 (在第 3 方网站上,它是一个用户脚本)

let anchor = document.createElement("a");
anchor.href = new URL("https://duckduckgo.com");
console.log(anchor);

//anchor.target = "_blank";
//anchor.rel = "nofollow noopener noreferrer";
//anchor.click();

运行这段代码在控制台中查看。

除了 web.archive.org

上的某些页面外,此代码在所有网站上都可以正常工作

例如:

https://web.archive.org/web/19961220154510/https://www.yahoo.com/

我明白了 <a href="https://web.archive.org/web/19961220154510if_/https://duckduckgo.com/"></a>,

但应该<a href="https://duckduckgo.com/"></a>.

.click()(就可以了)打开这个错URL.

如何解决?

它发生在 Chrome 和 Firefox 中。


UPD:window.open("https://duckduckgo.com") 也有问题。

它打开 https://web.archive.org/web/20080820060021/http://duckduckgo.com/ 而不是 https://duckduckgo.com/

发生这种情况是因为该站点上的 Javascript 正在覆盖 HTMLAnchorElement.prototype.href:

覆盖本机原型是一种不好的做法,会导致像这样令人困惑的错误。

对于用户脚本,您可以通过在页面加载开始时保存对 href 属性 描述符的引用来修复它,然后在错误 [=] 之后将其重新分配给 HTMLAnchorElement.prototype.href 31=] 代码已尝试重新分配它:

// ==UserScript==
// @name             0 New Userscript
// @include          https://web.archive.org/web/19961220154510/https://www.yahoo.com/
// @run-at           document-start
// @grant            none
// ==/UserScript==

const originalHrefDescriptor = Object.getOwnPropertyDescriptor(HTMLAnchorElement.prototype, 'href');
window.addEventListener('DOMContentLoaded', () => {
  Object.defineProperty(HTMLAnchorElement.prototype, 'href', originalHrefDescriptor);
  // Now, assigning to .hrefs results in normal behavior again
});

确保使用 // @run-at document-start 以确保您的用户脚本在页面上的任何代码运行之前运行 - 这样,您可以在描述符被覆盖之前保存对描述符的引用。

对于袋熊的这种特殊情况,您还可以给 a 一个 _no_rewrite 属性 而不是保存描述符:

const a = document.createElement('a');
a._no_rewrite = true;
a.href = 'https://www.google.com';