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

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

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

只有这一点是公认的:

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

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

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

157349 次浏览

XHTML 1规范的非规范性附录“超文本标记语言兼容性指南”说:

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

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

XHTML DTD将脚本元素指定为:

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

与XML和XHTML不同,超文本标记语言不知道自关闭语法。将XHTML解释为超文本标记语言的浏览器不知道/字符表示标签应该是自关闭的;相反,它们将其解释为空属性,解析器仍然认为标签是“打开的”。

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

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

即使是支持XHTML解析的浏览器,例如IE 9及以后,仍然会将文档解析为超文本标记语言,除非您为文档提供XML内容类型。但在这种情况下,旧的IE根本不会显示文档!

为了补充Brad和squadette所说的,自关闭XML语法<script />实际上正确的XML,但为了在实践中工作,您的Web服务器还需要将文档作为正确格式的XML发送,并在HTTP Content-Type标头中使用XML mimetypeapplication/xhtml+xml没有text/html)。

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

w3

简而言之,“应用程序/xhtml+xml”应该用于XHTML系列文件,以及“text/html”的使用应限于超文本标记语言兼容XHTML 1.0文档。“应用程序/xml”和'text/xml'也可以使用,但是在适当的时候,应该使用“Application/xhtml+xml”而不是那些通用的XML媒体类型。

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

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

无论是否摆弄http-equiv元元素、文档中的XML prolog或doctype,都会发生这种情况——Firefox一旦获得text/html标头就会分支,这决定了超文本标记语言或XML解析器是否在文档中查找,超文本标记语言解析器不理解<script />

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

XML的“短格式”被解释为一个名为/的属性,它(因为没有等号)被解释为具有一个隐含的值“/”。这在超文本标记语言4.01中是严格错误的-不允许未声明的属性-但浏览器会忽略它。

IE9和后来的支持XHTML5application/xhtml+xml一起使用。

上面的人已经基本上解释了这个问题,但有一件事可能会让事情变得清晰,尽管人们在超文本标记语言文档中一直使用<br/>等,但这种位置上的任何/基本上都被忽略了,并且只有在试图使某些东西既可解析为XML又可解析为超文本标记语言时才会使用。例如,尝试<p/>foo</p>,你会得到一个常规段落。

如果有人好奇,最终的原因是超文本标记语言最初是SGML的一种方言,SGML是XML奇怪的哥哥。在SGML领域,元素可以在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进行编码时,它会让你陷入困境。

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

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

如果你想让脚本标签自我封闭,你不能像我说的那样这样做,但有一个替代方案,尽管不是一个聪明的方案。你可以使用自关闭链接标签并链接到你的JavaScript,方法是给它一种text/javascript类型并rel作为脚本,如下所示:

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

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


超文本标记语言4

超文本标记语言4基于SGML

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

但是,超文本标记语言并没有进行编辑,因此<SCRIPT/>应该是的意思<SCRIPT>>。(是的,“>”应该是内容的一部分,标签仍然是没有关闭。)

显然,这与XHTML不兼容,打破了许多网站(到浏览器足够成熟的时候来照顾关于这个),所以没有人实施短板和规范反对他们的建议

实际上,所有“工作”自结束标签都是在技术上不符合的解析器上带有禁止结束标签的标签,实际上是无效的。是W3C想出了这个黑客通过使其超文本标记语言兼容来帮助过渡到XHTML。

<script>的结束标签是不禁止

“自结束”标签是超文本标记语言4中的一种黑客攻击,毫无意义。


超文本标记语言5

HTML5有五种类型的标签,只有“无效”和“外来”标签是允许自闭合

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

但是为什么呢?他们就不能把它看作是外国的,做个特例,或者别的什么吗?

超文本标记语言5的目标是向下兼容实现的超文本标记语言4和XHTML 1。它不是基于SGML或XML;它的语法主要涉及记录和统一实现。(这就是为什么<br/><hr/>等是有效的超文本标记语言5,尽管是无效的HTML4。

自关闭<script>是过去实现不同的标签之一。以前在Chrome工作Safari和Opera;据我所知,它从未在Internet Explorer或Firefox中工作过。

这已经讨论过了当超文本标记语言5被起草并被拒绝时,因为它打破浏览器兼容性。在旧浏览器中,自关闭脚本标记的网页可能无法正确呈现(如果有的话)。有其他提案,但也解决不了兼容性问题。

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

自关闭<script>在超文本标记语言5中不会发生,因为向后兼容超文本标记语言4和XHTML 1。


XHTML 1/XHTML 5

真的作为XHTML时,<script/>实际上是关闭的,正如其他答案所说。

除了规格说 it应该作为超文本标记语言时起作用:

XHTML文档…可以标记为Internet媒体类型“text/html”[RFC2854],因为它们与大多数超文本标记语言浏览器兼容。

那么,发生了什么事?

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

如果第一次浏览器大战没有以IE 6结束,XHTML可能也在列表中。但它确实结束了。和带有XHTML的IE 6有问题。事实上,IE不支持是正确的MIME类型在所有,迫使每个人对XHTML使用text/html,因为IE在整整十年中保持了主要市场份额

还有内容嗅探可以非常糟糕和人们说它应该被阻止

最后,事实证明W3C并不意味着XHTML是可嗅探的:文档两者,超文本标记语言和XHTML,以及Content-Type规则。可以说他们坚定地坚持“遵循我们的规范”和忽略了实际情况继续进入后来的XHTML版本的错误。

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

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

这是因为脚本标签不是一个空元素。

超文本标记语言文档-空隙元素不要中,根本需要一个“结束标签”!

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

但是,脚本元素永远不会是空或参数元素,因为脚本标签在其他任何东西之前,是浏览器指令,而不是数据描述声明。

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

<H1>语义学不能被下面的<P>终止,因为它没有足够的语义学来覆盖并终止之前的H1指令集。虽然它能够将分成一个新的段落行,但它还不够“强大”来覆盖当前的字体大小和样式line-高度顺流而下,即从H1泄漏(因为P没有它)。

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

< />这样的通用无描述终止标签足以解决遇到的级联中的任何一个脱落,例如:<H1>Title< />但并非总是如此,因为我们也希望能够“嵌套”,流的多个中介标签:在包装/落入另一个级联之前分裂成种子。因此,像< />这样的通用终止符将无法确定要终止的属性的目标。例如:<b>大胆<i>斜体字< /><H1>Title< />0</>正常。无疑会无法正确理解我们的意图,并且很可能会将其解释为<H1>Title< />1正常。

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

DIV元素实际上是一个2BR-Container。当然,CSS的出现使整个情况变得更加怪异,并引起了巨大的混乱,带来了许多巨大的后果——间接的!

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

CSS的到来具有完全覆盖和完全重新定义任何超文本标记语言Tag的本机行为的能力,以某种方式设法混淆和模糊了超文本标记语言存在的整个意义。

突然间,所有的超文本标记语言标签似乎都过时了,它们被污损了,被剥夺了所有原始的含义、身份和目的。不知何故,你会产生不再需要它们的印象。说:一个容器包装标签就足够了所有的数据表示。只需添加所需的属性。为什么不使用有意义的标签呢?

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

超文本标记语言的目的是来流式传输对人类接收者有意义的数据。

提供信息。

正式部分只是为了帮助内容分发的清晰度。XHTML根本不考虑信息。-对它来说,信息绝对无关紧要。

在这个问题上最重要的是知道并且能够理解XHTML不仅仅是一些扩展的超文本标记语言的版本,xhtml是一个完全不同的野兽;理由;因此把它们分开是明智的。

“真正的XHTML”,“人造XHTML”和“普通超文本标记语言”之间的区别以及服务器发送的MIME类型的重要性是这里已经描述得很好了

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

如您所见,根据嵌入文档的MIME类型,data-URI JavaScript功能要么执行并显示连续文本(在application/xhtml+xml模式下),要么不执行并被脚本“吞噬”连续文本(在text/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>

您应该在文本区域下方看到Hello, true XHTML. Nice to meet you!

对于无法使用的浏览器,您可以复制文本区域的内容并将其保存为扩展名为.xhtml(或.xht)(感谢Alek的这个提示)的文件。

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

标记省略无,起始和结束标记都是强制性的。

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