提问人:dimarzionist 提问时间:9/16/2008 最后编辑:Johndimarzionist 更新时间:6/4/2023 访问量:163833
为什么自闭合脚本元素不起作用?
Why don't self-closing script elements work?
问:
浏览器无法正确识别的原因是什么:
<script src="foobar.js" /> <!-- self-closing script element -->
只有这一点是公认的:
<script src="foobar.js"></script>
这是否打破了XHTML支持的概念?
注意:至少对于所有IE(6-8 beta 2)来说,这种说法是正确的。
答:
XHTML 1 规范的非规范性附录“HTML 兼容性指南”说:
给定内容模型不是的元素的空实例(例如,空标题或段落),不要使用最小化形式(例如,use 和 not )。
EMPTY
<p> </p>
<p />
XHTML DTD 将脚本元素指定为:
<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>
评论
<script />
与 XML 和 XHTML 不同,HTML 不了解自闭合语法。将 XHTML 解释为 HTML 的浏览器不知道该字符指示标记应该是自闭合的;相反,他们将其解释为空属性,并且解析器仍然认为标签是“打开的”。/
正如 被当作 一样,被当作 。<script defer>
<script defer="defer">
<script />
<script /="/">
评论
/
Internet Explorer 8 及更早版本不支持 XHTML 分析。即使您使用 XML 声明和/或 XHTML 文档类型,旧 IE 仍会将文档解析为纯 HTML。在纯 HTML 中,不支持自闭合语法。尾部斜杠被忽略,您必须使用显式结束标记。
即使是支持 XHTML 分析的浏览器(如 IE 9 及更高版本),仍将文档解析为 HTML,除非您使用 XML 内容类型提供文档。但是在这种情况下,旧的IE根本不会显示文档!
评论
为了补充 Brad 和 squadette 所说的内容,自闭合 XML 语法实际上是正确的 XML,但要让它在实践中工作,您的 Web 服务器还需要将文档作为格式正确的 XML 发送,其中包含 XML mimetype,如 HTTP Content-Type 标头(而不是 )。<script />
application/xhtml+xml
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 兼容)解决方案是使用旧语法 (HTML 语法 + HTML mimetype)。<script></script>
text/html
如果你的服务器在其HTTP头中发送类型,即使使用其他格式正确的XHTML文档,FF3+也会使用其HTML渲染模式,这意味着这将不起作用(这是一个变化,Firefox以前没有那么严格)。text/html
<script />
无论对文档中的元元素、XML prolog 或 doctype 进行任何摆弄,都会发生这种情况——Firefox 一旦获得标头,它就会分支,这决定了 HTML 或 XML 解析器是否查看文档内部,而 HTML 解析器无法理解。http-equiv
text/html
<script />
评论
.html
.xhtml
application/xhtml+xml
text/xml
Internet Explorer 8 及更早版本不支持 XHTML 的正确 MIME 类型。如果将 XHTML 作为 提供,则必须使这些旧版本的 Internet Explorer 执行任何操作,它将被解释为 HTML 4.01。您只能将短语法与任何允许省略结束标记的元素一起使用。请参阅 HTML 4.01 规范。application/xhtml+xml
text/html
XML“缩写形式”被解释为名为 / 的属性,该属性(因为没有等号)被解释为具有“/”的隐式值。这在 HTML 4.01 中是完全错误的 - 不允许未声明的属性 - 但浏览器会忽略它。
IE9 及更高版本支持 XHTML 5 和 .application/xhtml+xml
评论
上面的人已经差不多解释了这个问题,但有一件事可能会说清楚,尽管人们在 HTML 文档中一直使用 and 等等,但任何处于这种位置的人基本上都会被忽略,并且只在尝试将某些东西解析为 XML 和 HTML 时才使用。例如,尝试,你会得到一个常规的段落。<br/>
/
<p/>foo</p>
如果有人好奇,最终原因是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 进行编码时,它可能会让你陷入困境。
评论
P
DIV
P
DIV
</p>
自动关闭脚本标记将不起作用,因为脚本标记可以包含内联代码,并且 HTML 不够智能,无法根据属性的存在打开或关闭该功能。
另一方面,HTML 确实有一个很好的标签,用于包含 对外部资源的引用:标记,它可以是 自动关闭。它已经用于包含样式表、RSS 和 Atom 提要、规范 URI 和各种其他好东西。为什么不呢 JavaScript的?
<link>
如果你想让脚本标签是自封闭的,你不能像我说的那样这样做,但有一个替代方案,虽然不是一个聪明的。您可以使用自闭合链接标记并链接到您的 JavaScript,方法是为其提供一种 text/javascript 和 rel 作为脚本,如下所示:
<link type="text/javascript" rel ="script" href="/path/tp/javascript" />
评论
<style>
其他人回答了“如何”并引用了规格。这是“为什么不”的真实故事,经过数小时的挖掘错误报告和邮件列表。<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 解析。
评论
<p>
<li>
<p/>
这是因为 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是一个完全不同的野兽;地面;因此,将它们分开是明智的。
评论
“真正的 XHTML”、“人造 XHTML”和“普通 HTML”之间的区别以及服务器发送的 MIME 类型的重要性在这里已经很好地描述了。
如果您想立即尝试一下,这里有一个简单的可编辑片段,带有实时预览,包括自闭合脚本标记(请参阅 )和 XML 实体(不相关,请参见)。<script src="data:text/javascript,/*functionality*/" />
&x;
如您所见,根据嵌入文档的 MIME 类型,数据 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>
您应该在下面看到 textarea。Hello, true XHTML. Nice to meet you!
对于功能不强的浏览器,您可以复制文本区域的内容并将其保存为扩展名为(或)的文件(感谢 Alek 提供此提示)。.xhtml
.xht
简单地说,现代的答案是因为标签以这种方式表示为强制性的
标签省略 None,开始和结束标签都是必需的。
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script
评论