1468

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

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

只有这一点被认可:

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

这会破坏 XHTML 支持的概念吗?

注意:至少对于所有 IE (6-8 beta 2),此语句都是正确的。

4

12 回答 12

503

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

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

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

XHTML DTD将脚本元素指定为:

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>
于 2008-09-16T07:08:47.853 回答
250

补充一下 Brad 和小队所说的,自闭合 XML 语法<script />实际上正确的 XML,但要使其在实践中工作,您的 Web 服务器还需要将您的文档作为格式正确的 XML 发送,该 XML 具有类似于application/xhtml+xmlHTTP 中的 XML 模仿类型Content-Type 标头(而不是as text/html)。

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

w3

总之,'application/xhtml+xml' 应该用于 XHTML Family 文档,'text/html' 的使用应该限于与 HTML 兼容的 XHTML 1.0 文档。'application/xml' 和 'text/xml' 也可以使用,但在适当的时候,应该使用 'application/xhtml+xml' 而不是那些通用的 XML 媒体类型。

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

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

无论对元元素、文档中的 XML 序言或文档类型进行任何摆弄,都会发生这种情况http-equiv——Firefox 一旦获得text/html标题就会分支,这决定了 HTML 或 XML 解析器是否在文档内部查找,而 HTML 解析器不理解<script />.

于 2008-09-16T08:14:28.490 回答
197

其他人回答了“如何”并引用了规范。<script/>在深入研究错误报告和邮件列表数小时后,这是“为什么不”的真实故事。


HTML 4

HTML 4 基于SGML

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

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

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

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

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

“自结束”标签是 HTML 4 中的一个 hack,没有任何意义。


HTML 5

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

因为<script>不是 void(它可能有内容)并且不是外来的(如 MathML 或 SVG),<script>所以无论您如何使用它都不能自封闭。

但为什么?他们不能把它当作外国的,做特例之类的吗?

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

自闭合<script>是实现曾经不同的标签之一。它曾经在 Chrome、SafariOpera中工作;据我所知,它从未在 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/htmlXHTML,因为 IE占据了整整十年的主要市场份额

而且内容嗅探可能 非常糟糕,人们说应该停止它

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

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

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

于 2015-02-25T12:37:25.987 回答
178

万一有人好奇,归根结底的原因是HTML原本是SGML的方言,是XML的怪哥哥。在 SGML-land 中,可以在 DTD 中将元素指定为自关闭(例如 BR、HR、INPUT)、隐式可关闭(例如 P、LI、TD)或显式可关闭(例如 TABLE、DIV、SCRIPT)。当然,XML 没有这个概念。

现代浏览器使用的 tag-soup 解析器是从这个遗留下来的,尽管它们的解析模型不再是纯 SGML。当然,除非您使用 XML mime 类型发送它,否则您精心设计的 XHTML 会被视为受 SGML 启发的糟糕编写的标签汤。这也是为什么...

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

...被浏览器解释为:

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

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

于 2010-07-25T02:52:33.727 回答
44

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

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

于 2008-09-16T08:00:43.937 回答
28

上面的人已经对这个问题解释得差不多了,但是有一点可以说清楚的是,虽然人们<br/>一直在 HTML 文档中使用 and 这样的东西,但是/在这样的位置上的任何基本上都被忽略了,并且只在尝试制作时使用可以解析为 XML 和 HTML 的东西。例如,尝试<p/>foo</p>,您会得到一个常规段落。

于 2008-09-16T13:07:47.537 回答
24

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

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

如果你希望脚本标签是自封闭的,你不能像我说的那样做,但是有一个替代方案,虽然不是一个聪明的方案。您可以使用自闭合链接标签并通过给它一种 text/javascript 和 rel 作为脚本来链接到您的 JavaScript,如下所示:

<link type="text/javascript" rel ="script" href="/path/tp/javascript" />
于 2012-10-27T09:35:21.187 回答
22

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

就像<script defer>被对待一样<script defer="defer"><script />被当作对待<script /="/">

于 2008-09-16T07:10:59.220 回答
18

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 5application/xhtml+xml.

于 2008-09-16T12:48:14.137 回答
5

那是因为 SCRIPT TAG 不是 VOID ELEMENT。

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

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

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

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

<H1>语义不能被后续终止,<P>因为它没有携带足够的自身语义来覆盖并因此终止先前的 H1 指令集。虽然它能够将分成一个新的段落行,但它还不够“强大”来覆盖当前的字体大小和样式 line-height倾泻而下,即从 H1 泄漏(因为 P 没有它)。

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

一个通用的无描述终止标记,如< />, 就足以应付遇到的级联的任何单个脱落,例如:<H1>Title< />但情况并非总是如此,因为我们还希望能够“嵌套”,流的多个中间标记:split在包裹/落入另一个级联之前进入洪流。因此,通用终止器< />无法确定要终止的属性的目标。例如:<b>粗体 <i>粗体斜体 < /> 斜体 </>正常。毫无疑问,我们的意图是不正确的,并且很可能会将其解释为粗体-斜体粗体正常。

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

DIV 元素实际上是一个 2BR-Container。当然,CSS 的出现使整个情况变得比以前更奇怪,并造成了很大的混乱,产生了许多严重的后果——间接的!

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

CSS 的出现具有完全覆盖和重新定义任何 HTML 标签的本机行为的能力,以某种方式设法混淆和模糊了 HTML 存在的整个含义......

突然之间,所有的 HTML 标签都显得过时了,它们被污损,失去了所有原有的意义、身份和目的。不知何故,你会获得不再需要它们的印象。说:一个单独的容器包装标签就足够了所有的数据表示。只需添加所需的属性。为什么不使用有意义的标签呢?在你去的时候发明标签名称,让 CSS 来处理其余的事情。

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

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

传递信息。

正式部分只是为了帮助信息传递的清晰性。xhtml 丝毫不考虑这些信息。- 对它来说,信息是绝对不相关的。

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

于 2017-08-17T22:54:13.743 回答
3

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

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

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

于 2019-11-10T14:38:53.153 回答
2

“true XHTML”、“faux XHTML”和“普通 HTML”之间的区别以及服务器发送的 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!下面的文本区域。

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

于 2017-11-22T00:25:16.200 回答