为什么自闭合脚本元素不起作用?

Why don't self-closing script elements work?

提问人:dimarzionist 提问时间:9/16/2008 最后编辑:Johndimarzionist 更新时间:6/4/2023 访问量:163833

问:

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

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

只有这一点是公认的:

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

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

注意:至少对于所有IE(6-8 beta 2)来说,这种说法是正确的。

JavaScript HTML 互联网浏览器 XHTML

评论

16赞 corymathews 12/27/2008
适用于 Chrome 和 Opera
57赞 Adam Ness 10/25/2010
某些最新版本的 Chrome 似乎已经打破了这一点,自动关闭脚本标签在 Chrome 中不再起作用
14赞 DOK 3/19/2011
这不仅仅是脚本标签。我也不相信自动关闭 div 标签有效。
8赞 Martin Konicek 7/24/2011
截至 2011 年 7 月,Chrome 和 Firefox 都存在此问题。“这不是一个错误,而是一个功能”——真的很烦人。
4赞 Ciro Santilli OurBigBook.com 1/2/2014
两天后,有人问了更普遍的版本:stackoverflow.com/questions/97522/......

答:

513赞 squadette 9/16/2008 #1

XHTML 1 规范的非规范性附录“HTML 兼容性指南”说:

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

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

XHTML DTD 将脚本元素指定为:

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

评论

126赞 Konrad Rudolph 9/16/2008
不过,“不要”并不等同于“不能”。这是一个指南(为了兼容性,如章节标题所示),而不是规则。
55赞 squadette 9/16/2008
实际上,我找不到这个限制的任何用处:)这似乎完全是人为的。
22赞 hsivonen 10/9/2008
正确的答案是由olavk给出的。XHTML 1.0 的附录 C 并不是事情之所以如此的原因,而只是如何解决事情的本来面目。
33赞 Kornel 10/16/2008
它不是规范的规范部分。它只是关于如何处理不支持XHTML的浏览器的附录
13赞 Joe 7/29/2011
问题不在于规范不允许它,而在于如果内容类型不是 application/xhtml+xml,浏览器不会将其解释为“non-tag-soup”。参见:stackoverflow.com/questions/348736/... @shabunc:浏览器可能看起来可以理解它,但实际发生的事情是它将 <p/> 之后的内容放在段落,因为将 squadette 的引用解释为由于 <p> 是非空的,因此它不能是自动关闭的。在 XHTML 1.1 中,它可以是自闭合的。<script />
24赞 rpetrich 9/16/2008 #2

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

正如 被当作 一样,被当作 。<script defer><script defer="defer"><script /><script /="/">

评论

36赞 Alohci 2/22/2009
尽管这种解释很优雅,但实际上是错误的。如果为 true,则 DOM 中的脚本元素将有一个“/”属性。我检查了IE,Firefox和Opera,它们实际上都不包含这样的属性。
12赞 hallvors 8/17/2012
/ 不是有效的属性名称字符,因此会被丢弃。否则,这个解释就很清楚了。
2赞 IS4 11/8/2016
实际上,一些 HTML 解析器(尤其是验证器)可能会将 NET(Null End Tag)构造的一部分解释为。/
45赞 JacquesB 9/16/2008 #3

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

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

评论

9赞 EricLaw 8/13/2013
“IE 不支持 XHTML 解析”在编写本文时对 IE 版本是正确的,但现在不再是真的。
0赞 scunliffe 5/6/2014
您@EricLaw能澄清哪个版本的 IE 解决了这个问题吗?(以及任何特定条件 - 例如,需要有效的文档类型)
2赞 EricLaw 5/6/2014
@scunliffe IE9 是第一个完全支持 XHTML 的版本。blogs.msdn.com/b/ie/archive/2010/11/01/......
255赞 joelhardi 9/16/2008 #4

为了补充 Brad 和 squadette 所说的内容,自闭合 XML 语法实际上是正确的 XML,但要让它在实践中工作,您的 Web 服务器还需要将文档作为格式正确的 XML 发送,其中包含 XML mimetype,如 HTTP Content-Type 标头(而不是 )。<script />application/xhtml+xmltext/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 兼容)解决方案是使用旧语法 (HTML 语法 + HTML mimetype)。<script></script>text/html

如果你的服务器在其HTTP头中发送类型,即使使用其他格式正确的XHTML文档,FF3+也会使用其HTML渲染模式,这意味着这将不起作用(这是一个变化,Firefox以前没有那么严格)。text/html<script />

无论对文档中的元元素、XML prolog 或 doctype 进行任何摆弄,都会发生这种情况——Firefox 一旦获得标头,它就会分支,这决定了 HTML 或 XML 解析器是否查看文档内部,而 HTML 解析器无法理解。http-equivtext/html<script />

评论

3赞 Chris Moschini 4/10/2013
那么,如果您放弃对IE7的支持,发送text/xml将使您对<script/>的广泛浏览器支持,这是否正确?
8赞 Navin Israni 12/9/2013
因此,简而言之,仅当页面的 MIME 类型为 xhtml/xml 时,<script/> 才有效。对于常规的文本/html 页面,它将不起作用。而且,如果我们尝试使用“xhtml/xml”MIME 类型,它将破坏 IE 兼容性。总而言之,保持冷静并使用<脚本>......</script>谢谢乔;-)
1赞 alecov 1/8/2015
很好的解释。另一点值得注意的一点是,出于类似的原因,Firefox 也会将本地文件呈现为标签汤,而不管元标签如何。对于XHTML文件,Firefox只会在它们被命名为 时相应地呈现它们。.html.xhtml
0赞 TRiG 7/4/2017
@ChrisMoschini。可能,但使用 ,而不是 .application/xhtml+xmltext/xml
19赞 Mike Dimmick 9/16/2008 #5

Internet Explorer 8 及更早版本不支持 XHTML 的正确 MIME 类型。如果将 XHTML 作为 提供,则必须使这些旧版本的 Internet Explorer 执行任何操作,它将被解释为 HTML 4.01。您只能将短语法与任何允许省略结束标记的元素一起使用。请参阅 HTML 4.01 规范application/xhtml+xmltext/html

XML“缩写形式”被解释为名为 / 的属性,该属性(因为没有等号)被解释为具有“/”的隐式值。这在 HTML 4.01 中是完全错误的 - 不允许未声明的属性 - 但浏览器会忽略它。

IE9 及更高版本支持 XHTML 5 和 .application/xhtml+xml

评论

0赞 Damian Yerrick 3/13/2015
IE 9 支持 XHTML,IE 不再是 >51%。你能更新你的答案吗?
29赞 Marijn 9/16/2008 #6

上面的人已经差不多解释了这个问题,但有一件事可能会说清楚,尽管人们在 HTML 文档中一直使用 and 等等,但任何处于这种位置的人基本上都会被忽略,并且只在尝试将某些东西解析为 XML 和 HTML 时才使用。例如,尝试,你会得到一个常规的段落。<br/>/<p/>foo</p>

179赞 greim 7/25/2010 #7

如果有人好奇,最终原因是HTML最初是SGML的一种方言,SGML是XML奇怪的哥哥。在 SGML-land 中,可以在 DTD 中将元素指定为自闭合(例如 BR、HR、INPUT)、隐式可闭合(例如 P、LI、TD)或显式闭合(例如 TABLE、DIV、SCRIPT)。当然,XML对此没有概念。

现代浏览器使用的标签汤解析器就是从这个传统中演变而来的,尽管它们的解析模型不再是纯粹的 SGML。当然,你精心制作的XHTML被当作写得不好的SGML风格的标签汤,除非你用XML的MIME类型发送它。这也是为什么...

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

...被浏览器解释为:

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

...这是一个可爱的晦涩错误的秘诀,当你试图针对 DOM 进行编码时,它可能会让你陷入困境。

评论

6赞 Ahmed Aeon Axan 10/30/2013
我很好奇。为什么浏览器选择以这种方式解释它?
36赞 MrWhite 11/4/2013
@AhmedAeonAxan:元素不能包含元素(这是无效的 HTML),因此浏览器会在开始标记之前隐式关闭元素(定义为“式可关闭”)。然而,浏览器在这方面的行为确实会有所不同(就像它们可以处理任何无效的 HTML 一样)。PDIVPDIV
6赞 Mr Lister 12/17/2015
@ColeJohnson 不,这不是标签汤;greim 混淆了有效和无效 HTML 之间的边界。当作者不关心规则时,你会得到标签汤,因为浏览器使用纠错。另一方面,缺少结束标签实际上是 HTML 定义的一部分!</p>
3赞 greim 12/20/2015
@MrLister - 有点。“标签汤”描述的是 HTML 是如何解析的,而不是它是如何创作的。这是一个术语,用于描述浏览器用于理解 HTML 的不同策略,与严格的 XML 解析形成鲜明对比。XML解析只允许用于XML的MIME类型,但由于这些类型从未得到广泛使用,浏览器又回到了各种“标记汤”方案,即使对于其他有效的文档也是如此。
8赞 Stijn de Witt 1/9/2018
HTML5实际上标准化了“标签汤”的解析,包括处理无效标记的一致方法。在那之前,浏览器必须自己弄清楚如何处理无效标记,从而导致不一致。当前浏览器中的 HTML 解析器是有史以来最先进的软件之一。速度极快,可以处理大多数输入,产生一致的结果。
26赞 defau1t 10/27/2012 #8

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

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

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

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

评论

5赞 Josh M. 9/18/2013
我喜欢这样,不过为什么不“聪明”呢?
5赞 Dave Lawrence 3/27/2014
因为有一个预定义的脚本标签来精确地执行加载脚本的工作。你为什么要用别的东西来混淆问题?锤子敲打钉子..穿鞋会明智吗?
11赞 Jimbo Jonny 1/26/2016
@daveL - 我们有标签,但对外部CSS文件使用链接标签。链接标签的定义:“<link>标签定义文档和外部资源之间的链接。链接标签将用于外部 CSS 或 JS 似乎完全合乎逻辑......这就是它的用途......在外部文件中链接。注意我不是在谈论规范/跨浏览器/等,我只是在评论使用链接标签引入 CSS 和 JS 的逻辑性质......如果是这样的话,实际上会很有意义。不确定鞋子[类比]是否合适。<style>
216赞 Sheepy 2/25/2015 #9

其他人回答了“如何”并引用了规格。这是“为什么不”的真实故事,经过数小时的挖掘错误报告和邮件列表。<script/>


HTML全文 4

HTML 4 基于 SGML

SGML 有一些短标记,例如 、 、 或 。 XML 采用第一种形式,将结尾重新定义为“>”(SGML 是灵活的),因此它变成了 .<BR//<B>text</><B/text/<OL<LI>item</LI</OL><BR/>

但是,HTML 没有重新定义这一点,所以应该意味着 .
(是的,“>”应该是内容的一部分,并且标签仍关闭。
<SCRIPT/><SCRIPT>>

显然,这与XHTML不兼容,并且会破坏许多站点(当浏览器已经足够成熟到可以关心这一点时),因此没有人实现短标签并且规范建议不要使用它们。

实际上,所有“工作”的自结束标签都是在技术上不符合要求的解析器上带有禁止结束标签的标签,实际上是无效的。 W3C 提出了这个 hack,通过使其与 HTML 兼容来帮助过渡到 XHTML。

并且 的结束标签是不被禁止的。<script>

“Self-ending”标签是 HTML 4 中的一个 hack,毫无意义。


HTML 5的

HTML5 有五种类型的标签,只允许 'void' 和 'foreign' 标签是自闭合的。

因为它不是无效的(它可能有内容),也不是外来的(如 MathML 或 SVG),所以无论你如何使用它,都不能自闭合。<script><script>

但是为什么?难道他们不能把它看作是外国的,制造特例,或者别的什么吗?

HTML 5 旨在向后兼容 HTML 4 和 XHTML 1 的实现。 它不是基于SGML或XML;它的语法主要涉及记录和统一实现。 (这就是为什么 etc. 是有效的 HTML 5,尽管 HTML4 是无效的。<br/><hr/>

自闭合是过去实现不同的标记之一。 它曾经在 Chrome、Safari 和 Opera 中工作;据我所知,它从未在Internet Explorer或Firefox中起作用。<script>

这在起草 HTML 5 时被讨论过,但由于它破坏了浏览器兼容性而被拒绝。 自关闭脚本标记的网页可能无法在旧浏览器中正确呈现(如果有的话)。 还有其他建议,但它们也无法解决兼容性问题。

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

由于向后兼容 HTML 4 和 XHTML 1,因此在 HTML 5 中不会发生自闭合 <script>


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 类型,迫使每个人都使用 XHTML,因为 IE 在整整十年的时间里占据了主要的市场份额text/html

而且内容嗅探可能真的很糟糕,人们说应该停止它

最后,事实证明,W3C 并不意味着 XHTML 是可嗅探的:文档是 HTML 又是 XHTML,并且是规则。 可以说他们坚定地坚持“遵循我们的规范”,而忽略了实用的东西。这个错误一直延续到后来的XHTML版本中。Content-Type

无论如何,这个决定为Firefox解决了这个问题。 Chrome 诞生前 7 年;没有其他重要的浏览器。就这样决定了。

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

评论

1赞 Sheepy 3/16/2015
@AndyE 当你编写自闭合<script>时,当时各大浏览器并不认为它是闭合的,会把子序列html解析为javascript,导致有效的HTML5在这些老浏览器上被破坏。因此,该提案被拒绝。这在链接的 HTML5 邮件列表中进行了解释。
2赞 slebetman 12/9/2015
@AndyE:你所描述的是向前兼容性——旧代码与新编译器/解释器/解析器一起工作的能力。向后兼容性是指新代码能够与旧的编译器/解释器/解析器一起使用。所以,是的,向后兼容性是问题所在,否则以新规范编写的页面将无法在旧浏览器中工作(是的,这是 Web 编程的传统,尝试让新代码尽可能地在旧浏览器中工作)。
3赞 Sheepy 4/27/2016
@Dmitry 现实情况是,不允许自闭式脚本是一条单行道。由于链接的、自闭合的<脚本>将破坏所有浏览器,用户只会看到空白页——游戏机、互联网电视、公司 Win7 PC 上的 IE 11、数百万个 Java 运行时或数十亿个智能手机。您可以在大多数设备上升级大多数语言的大多数 WebView 吗?如果 HTML5 尝试这样做,它们就会像 XHTML2 一样失败。
10赞 Kamil Tomšík 8/21/2016
非常被低估的答案
2赞 Ilya Streltsyn 5/6/2017
稍作更正:在 HTML 中看似自闭合的标签不是带有可选结束标签的标签,而是带有禁止结束标签(空标签或 void 标签)的标签。带有可选结束标记(如 或 )的标记不能“自闭合”,因为它们可以包含内容,因此代码 like 只不过是(格式错误的)开始标记及其后面的内容(如果在此元素中允许)最终会进入其中。<p><li><p/>
6赞 Bekim Bacaj 8/18/2017 #10

这是因为 SCRIPT TAG 不是一个 VOID ELEMENT。

HTML 文档中 - VOID ELEMENTS 根本不需要“结束标签”!

xhtml 中,一切都是通用的,因此它们都需要终止,例如“结束标签”;包括 br,一个简单的换行符,as 或其简写<br></br><br />

但是,脚本元素从来都不是 void 或参数化元素,因为 script 标记首先是浏览器指令,而不是数据描述声明。

原则上,语义终止指令(例如,“结束标签”)仅用于处理语义不能被后续标签终止的指令。例如:

<H1>语义不能由跟随终止,因为它没有携带足够的语义来覆盖并因此终止先前的 H1 指令集。虽然它能够将分解成新的段落行,但它还不够“强大”,无法覆盖当前字体大小和样式行高,即从 H1 泄漏(因为 P 没有它)。<P>

这就是发明“/”(终止)信号的方式和原因。

像 这样的通用无描述终止标签就足以满足遇到的级联的任何单次下降,例如: 但情况并非总是如此,因为我们还希望能够“嵌套”,流的多个中间标记:在包装/落到另一个级联之前拆分为种子。因此,泛型终止符(如)无法确定要终止的属性的目标。例如:粗体斜体斜体正常。毫无疑问,我们的意图是无法实现的,并且很可能会将其解释为大胆的,< /><H1>Title< />< /><b><i>< /></>

包装器的概念就是这样诞生的,即容器。(这些概念是如此相似,以至于无法辨别,有时同一元素可能同时具有两者。 既是包装器又是容器。而只是一个语义包装器)。我们需要一个普通的、没有语义的容器。当然,DIV Element 的发明也随之而来。<H1><B>

DIV 元素实际上是一个 2BR-Container。当然,CSS的到来使整个情况变得比原来更奇怪,并造成了巨大的混乱,并间接地造成了许多巨大的后果!

因为使用 CSS,你可以很容易地覆盖新发明的 DIV 的原生 BR 前后行为,所以它通常被称为“不做任何事情的容器”。这自然是错误的!DIV 是块元素,将在结束信令之前和之后原生中断流的线路。很快,WEB就开始遭受页面DIV的困扰。他们中的大多数仍然是。

CSS的到来能够完全覆盖和完全重新定义任何HTML标签的原生行为,不知何故设法混淆和模糊了HTML存在的全部含义......

突然间,所有的HTML标签都显得好像过时了,它们被污损了,被剥夺了所有原始的含义、身份和目的。不知何故,你会觉得不再需要它们了。说:一个容器包装器标签就足以完成所有数据呈现。只需添加所需的属性即可。为什么不用有意义的标签来代替呢?随心所欲地发明标签名称,让 CSS 处理其余的。

xhtml 就是这样诞生的,当然也是大直率的,新来者付出了如此高昂的代价,以及对什么是什么的扭曲看法,以及这一切的该死的目的是什么。W3C 从万维网变成了出了什么问题,同志们?!!

HTML 的目的是将有意义的数据流式传输给人类接收者。

传递信息。

正式部分只是为了帮助信息传递的清晰度。 XHTML 对信息没有丝毫考虑。- 对它来说,信息是绝对无关紧要的。

最重要的是要知道并能够理解xhtml不仅仅是一些扩展HTML的一个版本,xhtml是一个完全不同的野兽;地面;因此,将它们分开是明智的。

评论

0赞 David Spector 5/4/2021
我认为HTML的目的是将数据流式传输到代理(通常是浏览器),热人。
4赞 myf 11/22/2017 #11

“真正的 XHTML”、“人造 XHTML”和“普通 HTML”之间的区别以及服务器发送的 MIME 类型的重要性在这里已经很好地描述了

如果您想立即尝试一下,这里有一个简单的可编辑片段,带有实时预览,包括自闭合脚本标记(请参阅 )和 XML 实体(不相关,请参见)。<script src="data:text/javascript,/*functionality*/" />&x;

如您所见,根据嵌入文档的 MIME 类型,数据 URI JavaScript 功能要么被执行并显示连续文本(在模式下),要么不执行,连续文本被脚本“吞噬”(在模式下)。application/xhtml+xmltext/html

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>

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

对于功能不强的浏览器,您可以复制文本区域的内容并将其保存为扩展名为(或)的文件(感谢 Alek 提供此提示)。.xhtml.xht

4赞 Mark Schultheiss 11/10/2019 #12

简单地说,现代的答案是因为标签以这种方式表示为强制性的

标签省略 None,开始和结束标签都是必需的。

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script

评论

0赞 David Spector 5/4/2021
如果给出 src 属性,则没有意义。但我想它使 HTML 更容易解析。