题 为什么自关闭脚本标签不起作用?


浏览器无法正确识别的原因是什么:

<script src="foobar.js" /> <!-- self-closing script tag -->

只有这一点得到承认:

<script src="foobar.js"></script>

这是否打破了XHTML支持的概念?

注意:此声明至少对所有IE(6-8 beta 2)都是正确的。


1155
2017-09-16 06:52


起源


适用于Chrome和Opera - corymathews
最新版本的Chrome似乎已经破坏了这一点,自动关闭脚本代码在Chrome中不再有效 - Adam Ness
它不仅仅是脚本标签。我不相信自我关闭div标签也可以。 - DOK
截至2011年7月,Chrome和Firefox都存在此问题。 “这不是一个错误,它是一个功能” - 真的很烦人。 - Martin Konicek
两天后问了更普遍的版本: stackoverflow.com/questions/97522/... - Ciro Santilli 新疆改造中心 六四事件 法轮功


答案:


XHTML 1规范说:

С.3。元素最小化和空元素内容

给定内容模型不是的元素的空实例 EMPTY (例如,空标题或段落)不使用最小化形式(例如使用 <p> </p> 并不是 <p />)。

XHTML DTD 将脚本标记指定为:

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>

419
2017-09-16 07:08



尽管如此,“不要”与“绝不”是不一样的。这是一个指南(兼容性,如章节标题所示),而非规则。 - Konrad Rudolph
实际上,我找不到这个限制的任何用途:)这看起来完全是人为的。 - squadette
奥拉夫克给出了正确的答案。 XHTML 1.0的附录C并不是事物本身的原因 - 它只是如何解决事物的方式。 - hsivonen
它不是规范的标准部分。这是关于如何处理浏览器的附录 不支持XHTML - Kornel
这个问题 <script /> 并不是规范不允许它,但如果内容类型不是application / xhtml + xml,浏览器不会将其解释为“非标签汤”。看到: stackoverflow.com/questions/348736/...  @shabunc:浏览器可能 出现 理解它,但实际发生的是它将内容放在<p />之后 内 段落,由于解释了squadette的引用意味着因为<p>非空,所以它不能自动关闭。在XHTML 1.1中,它 能够 自我关闭。 - Joe


添加Brad和squadette所说的,自动关闭的XML语法 <script /> 其实  正确的XML,但为了使其在实践中工作,您的Web服务器还需要将您的文档作为正确形成的XML与XML mimetype一起发送 application/xhtml+xml 在HTTP Content-Type标头中(和  如 text/html)。

但是,发送XML mimetype将导致您的页面不被IE7解析,IE7只喜欢 text/html

W3

总之,'application / xhtml + xml'   应该用于XHTML系列   文件,以及'text / html'的使用   应该限于HTML兼容   XHTML 1.0文档。 '应用程序/ XML'   也可以使用'text / xml',但是   适当时,   'application / xhtml + xml'应该被使用   而不是那些通用的XML媒体   类型。

几个月前我对此感到疑惑,唯一可行的(兼容FF3 +和IE7)解决方案是使用旧的 <script></script> 语法用 text/html (HTML语法+ HTML mimetype)。

如果您的服务器发送 text/html 键入其HTTP标头,即使使用其他正确形成的XHTML文档,FF3 +也将使用其HTML呈现模式,这意味着 <script /> 将无法工作(这是一个变化,Firefox以前不那么严格)。

无论如何摆弄都会发生这种情况 http-equiv 元标记,文档中的XML prolog或doctype - 一旦获得,它就会分支 text/html header,用于确定HTML或XML解析器是否在文档中查找,并且HTML解析器无法理解 <script />


211
2017-09-16 08:14



是否正确的结论是,如果您放弃对IE7的支持,发送text / xml将获得对<script />的广泛浏览器支持? - Chris Moschini
因此,简而言之,只有当页面的MIME类型为xhtml / xml时,<script />才有效。对于常规文本/ html页面,它将无法正常工作。如果我们尝试使用“xhtml / xml”MIME类型,它将破坏IE兼容性。总结一下,Keep Calm and Use <script> ... </ script>谢谢Joe ;-) - Navin Israni
优秀的解释。值得注意的另一点是Firefox也将拥有本地化 .html 出于类似的原因,无论元标记如何,呈现为标记 - 汤的文件。对于XHTML文件,Firefox只会在命名时对其进行相应的渲染 .xhtml。 - alecov
@ChrisMoschini。可能,但使用 application/xhtml+xml不是 text/xml。 - TRiG


如果有人好奇,最终的原因是HTML最初是SGML的方言,这是XML的奇怪的哥哥。在SGML-land中,标签可以在DTD中指定为自闭(例如BR,HR,INPUT),隐式可关闭(例如P,LI,TD)或明确可关闭(例如TABLE,DIV,SCRIPT)。 XML当然没有这个概念。

现代浏览器使用的标签汤解析器是从这种遗产中演化而来的,尽管它们的解析模型不再是纯粹的SGML。当然,除非您使用XML mime类型发送,否则您精心设计的XHTML将被视为编写得很糟糕的SGML风格的标签汤。这也是为什么......

<p><div>hello</div></p>

...被浏览器解释为:

<p></p><div>hello</div><p></p>

...这是一个可爱的模糊bug的配方,当你尝试对DOM进行编码时,它会让你陷入困境。


140
2017-07-25 02:52



我很好奇。为什么浏览器选择以这种方式解释它? - Ahmed Aeon Axan
@AhmedAeonAxan:The P 元素不能包含 DIV 元素(这是无效的HTML),所以浏览器 隐式 关闭了 P 开场前的元素(定义为“隐式可关闭”) DIV 标签。但是,浏览器在这方面的行为往往不同(因为它们可以处理任何无效的HTML)。 - MrWhite
@ w3d标签汤就像我们可以感谢Netscape或IE吗? - Cole Johnson
@ColeJohnson不,这不是标签汤; greim正在混淆有效和无效HTML之间的边界。标签汤是当作者不关心规则时得到的,因为浏览器使用纠错。一个失踪 </p> 另一方面,结束标记实际上是HTML定义的一部分! - Mr Lister
@MrLister - 排序。 “标签汤”描述了如何解析HTML,而不是如何编写。这个术语用于描述浏览器用于理解HTML的不同策略,与严格的XML解析形成鲜明对比。 XML解析仅允许用于XML mime类型,但由于那些从未得到广泛使用,浏览器会回归到各种“标签汤”方案,即使对于其他有效的文档也是如此。 - greim


其他人已回答“如何”和引用规范。这是真实的故事“为什么不 <script/>“,经过几个小时的挖掘bug报告和邮件列表。


HTML 4

HTML 4基于 SGML

SGML有一些 shorttags, 如 <BR//<B>text</><B/text/, 要么 <OL<LI>item</LI</OL>。 XML采用第一种形式,将结尾重新定义为“>”(SGML是灵活的),以便它成为 <BR/>

但是,HTML并没有重新定义,所以 <SCRIPT/>  应该 意思  <SCRIPT>>
(是的,'>'应该是内容的一部分,标签仍然是  关闭。)

显然,这与XHTML和XHTML不兼容  打破很多网站(当浏览器足够成熟时) 照顾  对这个),所以 没有人实施短标签 和规范 建议反对他们

实际上,所有“工作”自结尾标签都是带有可选结束标签的标签,这些标签位于技术上不符合的解析器上,实际上是无效的。 这是W3C 想出了这个黑客 通过制作它来帮助过渡到XHTML HTML兼容

<script>结束标签是 不是可选的

“自我结束”标签是HTML 4中的一个黑客,并且毫无意义。


HTML 5

HTML5有 五种类型的标签 只有'无效'和'外国'标签 允许自我关闭

因为 <script> 不是空的(它 可能 有内容)并且不是外国的(如MathML或SVG), <script> 无论你如何使用它都不能自我封闭。

但为什么?他们不能把它当作外国人,特殊情况或其他什么吗?

HTML 5旨在成为 向下兼容 同 实现 HTML 4和XHTML 1。 它不是基于SGML或XML;它的语法主要涉及记录和联合实现。 (这就是为什么 <br/>  <hr/> 等等 有效的HTML 5 尽管HTML4无效。)

自闭 <script> 是实现过去不同的标签之一。 它 曾经在Chrome,Safari中工作和歌剧;据我所知,它从未在Internet Explorer或Firefox中运行。

讨论了这一点 当HTML 5被起草并被拒绝时,因为它 休息  浏览器  兼容性。 自动关闭脚本标记的网页可能无法在旧浏览器中正确呈现(如果有的话)。 曾经有 其他提案,但他们也无法解决兼容性问题。

草稿发布后,WebKit更新了解析器以使其符合要求。

自闭 <script> 由于与HTML 4和XHTML 1的向后兼容性,HTML 5中不会发生这种情况。


XHTML 1 / XHTML 5

什么时候  作为XHTML, <script/> 真是封闭了,因为 其他答案 已经说过了。

除了那个 规范说 它 应该 在作为HTML提供时有效:

XHTML文档...可能标有Internet媒体类型“text / html”[RFC2854],因为它们与大多数HTML浏览器兼容。

所以发生了什么事?

Mozilla问道 至 让Firefox解析 符合文件 XHTML 无论指定的内容标头如何(称为 内容嗅探)。 这将允许自动关闭脚本和内容嗅探 是必要的 无论如何,因为网络主机不够成熟,无法提供正确的标题; IE是 擅长

如果 第一次浏览器大战 没有以IE 6结尾,XHTML也可能已经列入名单。但它确实结束了。和IE 6 有问题 使用XHTML。 实际上IE 不支持 正确的MIME类型 一点都不,强迫 大家 使用 text/html 对于XHTML因为IE 拥有主要的市场份额 整整十年。

还有内容嗅探   特别糟糕 人们都说 应该停止

最后,事实证明是W3C 并不意味着XHTML是可以嗅探的:文件是 ,HTML和XHTML,以及 Content-Type 规则。 可以说他们坚持“只要按照我们的规范”和 忽略了实际的东西。一个错误 继续 进入后来的XHTML版本。

无论如何,这个决定 解决了这件事 对于Firefox。 这是Chrome之前的7年 出生于;没有其他重要的浏览器。因此决定了。

由于以下规范,仅指定doctype不会触发XML解析。


123
2018-02-25 12:37



@AndyE当你编写自动关闭<script>时,当时的主要浏览器不认为它已关闭,并将子序列html解析为javascript,导致有效的HTML5在这些旧浏览器上中断。因此该提案被拒绝。这在链接的HTML5邮件列表中进行了解释。 - Sheepy
目前还不清楚提案被拒绝的主要原因,因为讨论结束时非常突然,尽管用新代码破坏现有浏览器是提出的问题之一。我只是指出了这一点 <script>作为允许自动关闭的HTML5元素将是唯一的。我在第一次评论中的意思是向后兼容性没有受到损害,因为向后兼容性是指在较新的浏览器中运行的旧代码 - 在这种情况下这很好。 - Andy E
@AndyE:你所描述的是向前兼容性 - 旧代码与新编译器/解释器/解析器一起工作的能力。向后兼容性是新代码与旧编译器/解释器/解析器一起使用的能力。所以,是的,向后兼容性是问题,否则用新规范编写的页面在旧浏览器中不起作用(是的,它是Web编程的传统,尝试尽可能地使新代码在旧浏览器中工作)。 - slebetman
@Dmitry现实情况是,不允许自闭剧本是一条单行道。如 关联,自闭的<script>会破裂 所有 浏览器,用户只会看到空白页 - 游戏机,互联网电视,IE 11上 新 企业Win7 PC,数百万 Java运行时,或数十亿的智能手机。您能在大多数设备上升级大多数语言的大多数WebView吗?如果HTML5尝试过它们会像XHTML2一样失败。 - Sheepy
非常低估的答案 - Kamil Tomšík


Internet Explorer 8及更早版本不支持XHTML解析。即使您使用XML声明和/或XHTML doctype,旧的IE仍然将文档解析为纯HTML。在纯HTML中,不支持自动关闭语法。只是忽略尾部斜杠,您必须使用显式结束标记。

甚至支持XHTML解析的浏览器,例如 IE 9及更高版本,仍然会将文档解析为HTML,除非您使用XML内容类型提供文档。但在这种情况下,旧的IE将根本不显示文档!


43
2017-09-16 08:00



“IE不支持XHTML解析。”在编写本文时,IE版本是正确的,但不再是真的。 - EricLaw
@EricLaw你能澄清哪个版本的IE修好了吗? (以及任何特定条件 - 例如需要有效的doctype) - scunliffe
@scunliffe IE9是第一个完全支持XHTML的版本。 blogs.msdn.com/b/ie/archive/2010/11/01/... - EricLaw


上面的人已经解释了这个问题,但有一件事可能会让事情变得清晰,尽管人们会使用 '&lt;br/>' 这样的所有时间 HTML 文件,任何 '/' 在这样的位置基本上被忽略了,并且只在尝试制作既可解析的东西时使用 XML 和 HTML。尝试 '&lt;p/>foo&lt;/p>'例如,你得到一个常规段落。


25
2017-09-16 13:07





自闭脚本标记不起作用,因为脚本标记可以包含内联代码,并且HTML不够智能,无法根据属性的存在打开或关闭该功能。

另一方面,HTML确实有一个很好的标签包括   对外部资源的引用: <link>标签,它可以   自闭。它已经用于包括样式表,RSS和Atom   提要,规范URI和各种其他好东西。为什么不   JavaScript的?

如果你想让脚本标签自我封闭你不能像我说的那样做,但有一个替代方案,但不是一个聪明的方法。您可以使用自闭链接标记并通过为其提供一种text / javascript和rel作为脚本链接到您的JavaScript,如下所示:

<link type="text/javascript" rel ="script" href="/path/tp/javascript" />

23
2017-10-27 09:35



我喜欢那样,为什么不“聪明”呢? - Josh M.
因为有一个预定义的脚本标签可以完全执行加载脚本的工作。为什么要使用别的东西来混淆问题呢?锤子钉在钉子上..使用鞋子会很聪明吗? - Dave Lawrence
@daveL - 我们有 <style> 标签,但使用外部CSS文件的链接标签。链接标签的定义: “<link>标签定义了文档和外部资源之间的链接。” 似乎完全合乎逻辑的是,链接标记将用于外部CSS或JS ...这就是它...用于链接外部文件。 注意 我不是在谈论规范/跨浏览器/等等,我只是评论使用链接标签引入CSS和JS的逻辑性质......如果是这样的话,它实际上会有很多意义。鞋子[类比]不合适。 - Jimbo Jonny


与XML和XHTML不同,HTML不了解自动关闭语法。将XHTML解释为HTML的浏览器不知道 / 字符表示标签应该是自动关闭的;相反,他们将其解释为一个空属性,解析器仍然认为标签是“开放的”。

就像 <script defer> 被视为 <script defer="defer"><script /> 被视为 <script /="/">


19
2017-09-16 07:10



这个解释很优雅,实际上是错误的。如果是,则DOM中的script元素将有“/”属性。我已经检查过IE,Firefox和Opera,但它们都没有包含这样的属性。 - Alohci
/不是有效的属性名称字符,因此它被丢弃。否则这个解释很清楚。 - hallvors
实际上,一些HTML解析器(尤其是验证器)可以解释 / 作为NET(Null End Tag)构造的一部分。 - IllidanS4


Internet Explorer 8及更早版本不支持XHTML的正确MIME类型, application/xhtml+xml。如果你正在服务XHTML text/html,你必须为这些旧版本的Internet Explorer做任何事情,它将被解释为HTML 4.01。您只能将短语法与允许省略结束标记的任何元素一起使用。见 HTML 4.01规范

XML“简短形式”被解释为名为/的属性,其(因为没有等号)被解释为具有隐含值“/”。这在HTML 4.01中是严格错误的 - 不允许使用未声明的属性 - 但浏览器会忽略它。

IE9及更高版本 支持XHTML 5 配上 application/xhtml+xml


18
2017-09-16 12:48



IE 9支持XHTML和IE不再> 51%。你能更新你的答案吗? - Damian Yerrick


'真XHTML','虚假XHTML'和HTML之间的区别以及服务器发送的MIME类型的重要性已经 这里已经很好地描述了。如果你想立即试用,这里有一个简单的可编辑片段,带有实时预览,包括适用于浏览器的自闭脚本标签:

div { display: flex; }
div + div {flex-direction: column; }
<div>Mime type: <label><input type="radio" onchange="t.onkeyup()" id="x" checked  name="mime"> application/xhtml+xml</label>
<label><input type="radio" onchange="t.onkeyup()" name="mime"> text/html</label></div>
<div><textarea id="t" rows="4" 
onkeyup="i.src='data:'+(x.checked?'application/xhtml+xml':'text/html')+','+encodeURIComponent(t.value)"
><?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
[<!ENTITY x "true XHTML">]>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
  <p>
    <span id="greet" swapto="Hello">Hell, NO :(</span> &x;.
    <script src="data:text/javascript,(g=document.getElementById('greet')).innerText=g.getAttribute('swapto')" />
    Nice to meet you!
    <!-- 
      Previous text node and all further content falls into SCRIPT element content in text/html mode, so is not rendered. Because no end script tag is found, no script runs in text/html
    -->
  </p>
</body>
</html></textarea>

<iframe id="i" height="80"></iframe>

<script>t.onkeyup()</script>
</div>

你应该看到 Hello, true XHTML. Nice to meet you! 在textarea下面。

对于无法使用的浏览器,您可以复制textarea的内容并将其另存为文件 .xhtml (要么 .xht) 延期 (感谢Alek的这个暗示)。


3
2017-11-22 00:25