超链接 href 在 innerHTML 中被错误引用?
Hyperlink href incorrectly quoted in innerHTML?
举这个非常简单的例子HTML:
<html>
<body>This is okay & fine, but the encoding of <a href="http://example.com?a=1&b=2">this link</a> seems wrong.</body>
<html>
在检查 document.body.innerHTML
时(例如在浏览器的 JS 控制台中,在 JS 本身中等),这是我看到的值:
This is okay & fine, but the encoding of <a href="http://example.com?a=1&b=2">this link</a> seems wrong.
这种行为在不同浏览器中都是相同的,但我无法理解,这似乎是错误的。
具体来说,原始文档中的link是http://example.com?a=1&b=2
,而如果innerHTML
的值被视为HTML那么它link s 到 http://example.com?a=1&b=2
这是不一样的(例如,如果我创建了一个新文档,它实际上有 innerHTML
作为它的内部 HTML,然后我点击了 link 然后据我所知,浏览器将被发送到一个完全不同的 URL。
(编辑#3:我错了。首先,是的,这两个 URL 是不同的;但其次,我认为错误的 innerHTML
是正确的,它正确地代表了第一个 URL,而不是第二个!请参阅下面我自己的答案的结尾。)
这与问题 innerHTML gives me & as & ! 中讨论的问题不同。在我的情况下(与该问题的情况相反)原始 HTML 是正确的,在我看来好像 innerHTML
是错误的(即因为它是 HTML 不代表原来的 HTML 代表什么)。
(编辑#2:我也错了:这并没有什么不同。但我认为 &
是在href,不只是在正文中。一旦你意识到这一点,你就会发现这些实际上是同一个问题。)
谁能解释一下?
(编辑#1+4:这只是在我写完我最初的问题后才想到的,但是:“&
在 href 文本 [=56] 中实际上是正确的 =],并且 &
在技术上是不正确的?”正如我第一次写这些话时所说的那样,“似乎不太可能!我当然从未见过 HTML 是这样写的。”但是 'unlikely', 或不是, 是这样的, 是我不理解的主要部分!)
也相关并且很有用,谁能解释如何清楚地得到 HTML 哪个 正确表示文档 link 的目标?您绝对不能只取消编码 innerHTML
中的所有 HTML 字符引用,因为(如我使用的示例所示,也如 innerHTML gives me & as & ! 中所讨论)文本 的主要 运行 应该 被编码,并且只是取消编码所有内容都会使这些错误。
我最初认为这不是 innerHTML gives me & as & ! 的重复(如上所述;并且在某种程度上它仍然不是,如果它同意同样的问题适用并不那么明显或广为人知在 href 内,如在正文中)。它仍然绝对不是 的副本(有些不清楚地询问如何使用 JS 设置 innerHTML
)。
想出一个可能的(但我认为 'unlikely')解释 - 我在原始问题中作为编辑输入 - 我意识到它 是 答案:
- 在 href 中使用
&
表示 &
在技术上是不正确的,而 &
在技术上是正确的
我最初是从这个 SO answer https://whosebug.com/a/16168585/795690 中收集到的,我认为相关的是(正如它在该答案中所说的那样)&
是表示 &
在 href 中并不像 &
是在 body 文本中表示 &
的正确方法那样被广泛理解。
一旦您理解了这一点,就会明白浏览器所做的是正确的,并且返回的 innerHTML
值代表 link 正确。
编辑:
@ÁlvaroGonzález 给出了更长的答案,我花了一段时间才明白他所说的一切是如何应用的,所以我想我会尝试从我开始的地方开始解释我不明白的地方,在万一它能帮助到别人呢!
如果你从 HTML 和 <a href="http://example.com/?a=1&b=1">
开始,然后在浏览器中检查 DOM,或者查看 JS 中 href 属性的值,你会看到 "http://example.com/?a=1&b=1"
无处不在。所以看起来好像什么都没有改变,也没有什么不对劲。我不明白的是,实际上浏览器已经解析了一个技术上不正确的 href(带有无效的实体)以便能够向您显示它! (是的,很多人使用这种 'broken' 格式!)
要亲身体验,请将这个更长的 HTML 示例加载到您的浏览器中:
<html>
<body style="font-family: sans-serif">
<p>Now & then <a href="http://example.com/?a=1&b=2">http://example.com/?a=1&b=2</a></p>
<p>Now & then <a href="http://example.com/?a=1&b=2">http://example.com/?a=1&b=2</a></p>
<p>Now &amp; then <a href="http://example.com/?a=1&amp;b=2">http://example.com/?a=1&amp;b=2</a></p>
</body>
</html>
然后在您的 javascript 控制台中尝试 运行 此代码取自@ÁlvaroGonzález 的回答:
const paragraphs = document.querySelectorAll("p");
for (p of paragraphs) {
console.log(p.innerHTML);
}
const links = document.querySelectorAll("a");
for (a of links) {
console.log(a.getAttribute("href"));
}
也可以尝试单击 link 以查看它们的去向。
一旦您理解了在那里看到的所有内容,就不会再对 innerHTML
的工作方式感到惊讶了!
大多数浏览器工具不显示实际的 HTML 因为它不会有太大帮助:
- HTML 通常在页面加载后借助 CSS 和 JavaScript.
动态生成
- HTML 经常损坏,浏览器需要修复它以生成渲染和其他内容所需的内存表示。
所以您看到的 HTML 不是实际来源,而是根据文档的当前状态动态生成的,其中当然包括所有固定应用(在您的情况下,无效 HTML 个实体)。
以下示例有望说明所有组合:
const section = document.querySelector("section");
const invalid = document.createElement("p");
invalid.innerHTML = '<a href="http://example.com/?a=1&b=2">Invalid HTML (dynamic)</a>';
const valid = document.createElement("p");
valid.innerHTML = '<a href="http://example.com/?a=1&b=2">Valid HTML (dynamic)</a>';
section.appendChild(valid);
section.appendChild(invalid);
const paragraphs = document.querySelectorAll("p");
for (p of paragraphs) {
console.log(p.innerHTML);
}
const links = document.querySelectorAll("a");
for (a of links) {
console.log(a.getAttribute("href"));
}
<section>
<p><a href="http://example.com/?a=1&b=2">Invalid HTML (static)</a></p>
<p><a href="http://example.com/?a=1&b=2">Valid HTML (static)</a></p>
<section>
Is &
actually correct within the href text, and &
technically incorrect? It seems very unlikely! I've certainly never seen HTML written that way.
没有“技术上正确”这样的东西,更不用说今天 HTML 已经非常标准化了。 (嗯,是的,有两个相互竞争的标准机构,规范也在不断发展,但基础知识早就建立了。)
&
符号开始一个字符实体,&b
是一个无效的字符实体。期间.
但它有效!这是否意味着它技术上是正确的?
之所以有效,是因为浏览器明确设计用于处理完全损坏的标记,即所谓的标签汤,因为人们认为它会简化使用:
<p><strong>Hello, World!</u>
<body><br itspartytime="yeah">
<pink>It works!!!</red>
但是 HTML 实体只是一种编码产物。这并不意味着 URL 不允许包含文字和符号,它只是意味着 - 当在 HTML 上下文中时 - 它们需要 表示 为 &
.这与在 JavaScript 字符串中键入反斜杠以转义某些引号相同:反斜杠不会成为数据的一部分。
举这个非常简单的例子HTML:
<html>
<body>This is okay & fine, but the encoding of <a href="http://example.com?a=1&b=2">this link</a> seems wrong.</body>
<html>
在检查 document.body.innerHTML
时(例如在浏览器的 JS 控制台中,在 JS 本身中等),这是我看到的值:
This is okay & fine, but the encoding of <a href="http://example.com?a=1&b=2">this link</a> seems wrong.
这种行为在不同浏览器中都是相同的,但我无法理解,这似乎是错误的。
具体来说,原始文档中的link是http://example.com?a=1&b=2
,而如果innerHTML
的值被视为HTML那么它link s 到 http://example.com?a=1&b=2
这是不一样的(例如,如果我创建了一个新文档,它实际上有 innerHTML
作为它的内部 HTML,然后我点击了 link 然后据我所知,浏览器将被发送到一个完全不同的 URL。
(编辑#3:我错了。首先,是的,这两个 URL 是不同的;但其次,我认为错误的 innerHTML
是正确的,它正确地代表了第一个 URL,而不是第二个!请参阅下面我自己的答案的结尾。)
这与问题 innerHTML gives me & as & ! 中讨论的问题不同。在我的情况下(与该问题的情况相反)原始 HTML 是正确的,在我看来好像 innerHTML
是错误的(即因为它是 HTML 不代表原来的 HTML 代表什么)。
(编辑#2:我也错了:这并没有什么不同。但我认为 &
是在href,不只是在正文中。一旦你意识到这一点,你就会发现这些实际上是同一个问题。)
谁能解释一下?
(编辑#1+4:这只是在我写完我最初的问题后才想到的,但是:“&
在 href 文本 [=56] 中实际上是正确的 =],并且 &
在技术上是不正确的?”正如我第一次写这些话时所说的那样,“似乎不太可能!我当然从未见过 HTML 是这样写的。”但是 'unlikely', 或不是, 是这样的, 是我不理解的主要部分!)
也相关并且很有用,谁能解释如何清楚地得到 HTML 哪个 正确表示文档 link 的目标?您绝对不能只取消编码 innerHTML
中的所有 HTML 字符引用,因为(如我使用的示例所示,也如 innerHTML gives me & as & ! 中所讨论)文本 的主要 运行 应该 被编码,并且只是取消编码所有内容都会使这些错误。
我最初认为这不是 innerHTML gives me & as & ! 的重复(如上所述;并且在某种程度上它仍然不是,如果它同意同样的问题适用并不那么明显或广为人知在 href 内,如在正文中)。它仍然绝对不是 innerHTML
)。
想出一个可能的(但我认为 'unlikely')解释 - 我在原始问题中作为编辑输入 - 我意识到它 是 答案:
- 在 href 中使用
&
表示&
在技术上是不正确的,而&
在技术上是正确的
我最初是从这个 SO answer https://whosebug.com/a/16168585/795690 中收集到的,我认为相关的是(正如它在该答案中所说的那样)&
是表示 &
在 href 中并不像 &
是在 body 文本中表示 &
的正确方法那样被广泛理解。
一旦您理解了这一点,就会明白浏览器所做的是正确的,并且返回的 innerHTML
值代表 link 正确。
编辑:
@ÁlvaroGonzález 给出了更长的答案,我花了一段时间才明白他所说的一切是如何应用的,所以我想我会尝试从我开始的地方开始解释我不明白的地方,在万一它能帮助到别人呢!
如果你从 HTML 和 <a href="http://example.com/?a=1&b=1">
开始,然后在浏览器中检查 DOM,或者查看 JS 中 href 属性的值,你会看到 "http://example.com/?a=1&b=1"
无处不在。所以看起来好像什么都没有改变,也没有什么不对劲。我不明白的是,实际上浏览器已经解析了一个技术上不正确的 href(带有无效的实体)以便能够向您显示它! (是的,很多人使用这种 'broken' 格式!)
要亲身体验,请将这个更长的 HTML 示例加载到您的浏览器中:
<html>
<body style="font-family: sans-serif">
<p>Now & then <a href="http://example.com/?a=1&b=2">http://example.com/?a=1&b=2</a></p>
<p>Now & then <a href="http://example.com/?a=1&b=2">http://example.com/?a=1&b=2</a></p>
<p>Now &amp; then <a href="http://example.com/?a=1&amp;b=2">http://example.com/?a=1&amp;b=2</a></p>
</body>
</html>
然后在您的 javascript 控制台中尝试 运行 此代码取自@ÁlvaroGonzález 的回答:
const paragraphs = document.querySelectorAll("p");
for (p of paragraphs) {
console.log(p.innerHTML);
}
const links = document.querySelectorAll("a");
for (a of links) {
console.log(a.getAttribute("href"));
}
也可以尝试单击 link 以查看它们的去向。
一旦您理解了在那里看到的所有内容,就不会再对 innerHTML
的工作方式感到惊讶了!
大多数浏览器工具不显示实际的 HTML 因为它不会有太大帮助:
- HTML 通常在页面加载后借助 CSS 和 JavaScript. 动态生成
- HTML 经常损坏,浏览器需要修复它以生成渲染和其他内容所需的内存表示。
所以您看到的 HTML 不是实际来源,而是根据文档的当前状态动态生成的,其中当然包括所有固定应用(在您的情况下,无效 HTML 个实体)。
以下示例有望说明所有组合:
const section = document.querySelector("section");
const invalid = document.createElement("p");
invalid.innerHTML = '<a href="http://example.com/?a=1&b=2">Invalid HTML (dynamic)</a>';
const valid = document.createElement("p");
valid.innerHTML = '<a href="http://example.com/?a=1&b=2">Valid HTML (dynamic)</a>';
section.appendChild(valid);
section.appendChild(invalid);
const paragraphs = document.querySelectorAll("p");
for (p of paragraphs) {
console.log(p.innerHTML);
}
const links = document.querySelectorAll("a");
for (a of links) {
console.log(a.getAttribute("href"));
}
<section>
<p><a href="http://example.com/?a=1&b=2">Invalid HTML (static)</a></p>
<p><a href="http://example.com/?a=1&b=2">Valid HTML (static)</a></p>
<section>
Is
&
actually correct within the href text, and&
technically incorrect? It seems very unlikely! I've certainly never seen HTML written that way.
没有“技术上正确”这样的东西,更不用说今天 HTML 已经非常标准化了。 (嗯,是的,有两个相互竞争的标准机构,规范也在不断发展,但基础知识早就建立了。)
&
符号开始一个字符实体,&b
是一个无效的字符实体。期间.
但它有效!这是否意味着它技术上是正确的?
之所以有效,是因为浏览器明确设计用于处理完全损坏的标记,即所谓的标签汤,因为人们认为它会简化使用:
<p><strong>Hello, World!</u>
<body><br itspartytime="yeah">
<pink>It works!!!</red>
但是 HTML 实体只是一种编码产物。这并不意味着 URL 不允许包含文字和符号,它只是意味着 - 当在 HTML 上下文中时 - 它们需要 表示 为 &
.这与在 JavaScript 字符串中键入反斜杠以转义某些引号相同:反斜杠不会成为数据的一部分。