【问题标题】:Why don't self-closing script elements work?为什么自闭合脚本元素不起作用?
【发布时间】:2010-09-09 08:29:24
【问题描述】:

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

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

只有这个被识别:

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

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

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

【问题讨论】:

  • 在 Chrome 和 Opera 中工作
  • 某些最新版本的 Chrome 似乎已经破坏了这一点,自关闭脚本标签在 Chrome 中不再起作用
  • 不仅仅是脚本标签。我也不相信自动关闭的 div 标签可以工作。
  • 截至 2011 年 7 月,Chrome 和 Firefox 都存在此问题。 “这不是错误,而是功能”——真的很烦人。
  • 两天后有人问了这个更通用的版本:stackoverflow.com/questions/97522/…

标签: javascript html internet-explorer xhtml


【解决方案1】:

XHTML 1 规范说:

С.3. Element Minimization and Empty Element Content

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

XHTML DTD 指定脚本元素为:

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

【讨论】:

  • 不过,“不要”与“不得”不同。这是一个指导方针(为了兼容性,正如小节标题所建议的那样),而不是规则。
  • 其实我找不到这个限制有什么用处:) 看起来完全是人为的。
  • olavk给出了正确答案。 XHTML 1.0 的附录 C 并不是事情是这样的原因——它只是如何解决事情的本来面目。
  • 这不是规范的规范部分。只是关于如何处理不支持XHTML的浏览器的附录
  • &lt;script /&gt; 的问题不在于规范不允许,而是如果内容类型不是 application/xhtml+xml,浏览器不会将其解释为“non-tag-soup”。请参阅:stackoverflow.com/questions/348736/…@shabunc:浏览器可能似乎理解它,但实际发生的是将内容放在

    inside 段落之后,由于将小队的引述解释为,由于

    是非空的,因此它不能自动关闭。在 XHTML 1.1 中,它可以自动关闭。

【解决方案2】:

补充一下 Brad 和小队所说的,自闭合 XML 语法 &lt;script /&gt; 实际上 正确的 XML,但要使其在实践中工作,您的 Web 服务器还需要发送您的文档为格式正确的 XML,在 HTTP Content-Type 标头中具有类似 application/xhtml+xml 的 XML mimetype(并且 nottext/html)。

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

来自w3

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

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

如果您的服务器在其 HTTP 标头中发送 text/html 类型,即使使用其他格式正确的 XHTML 文档,FF3+ 将使用其 HTML 呈现模式,这意味着 &lt;script /&gt; 将不起作用(这是一个变化,Firefox 以前是不太严格)。

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

【讨论】:

  • 如果您放弃对 IE7 的支持,发送 text/xml 将获得对 的广泛浏览器支持,是否正确?
  • 因此,简而言之, 只有在您的页面的 MIME 类型是 xhtml/xml 时才有效。对于常规的 text/html 页面,它不起作用。如果我们确实尝试使用“xhtml/xml”MIME 类型,它会破坏 IE 兼容性。总而言之,保持冷静并使用 谢谢 Joe ;-)
  • 很好的解释。值得注意的另一点是,出于类似的原因,Firefox 也会将本地 .html 文件呈现为标签汤,而不管元标签如何。对于 XHTML 文件,Firefox 只会在它们被命名为 .xhtml 时相应地呈现它们。
  • @ChrisMoschini。可能,但使用application/xhtml+xml,而不是text/xml
【解决方案3】:

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


HTML 4

HTML 4 基于SGML

SGML 有一些shorttags,例如&lt;BR//&lt;B&gt;text&lt;/&gt;&lt;B/text/&lt;OL&lt;LI&gt;item&lt;/LI&lt;/OL&gt;。 XML 采用第一种形式,将结尾重新定义为“>”(SGML 是灵活的),这样就变成了&lt;BR/&gt;

但是,HTML 没有重新定义,所以 &lt;SCRIPT/&gt; should mean &lt;SCRIPT&gt;&gt;
(是的,'>' 应该是内容的一部分,并且标签仍然是 not 关闭的。)

显然,这与 XHTML 不兼容,破坏许多网站(到浏览器足够成熟时 to care about this),所以 nobody implemented shorttags 和规范 advises against them

实际上,所有“工作”的自结束标签都是在技术上不符合标准的解析器上带有禁止结束标签的标签,实际上是无效的。 是 W3C 的 came up with this hack 通过将其设为 HTML-compatible 来帮助过渡到 XHTML。

&lt;script&gt;的结束标签是not prohibited

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


HTML 5

HTML5 有five types of tags,只有'void'和'foreign'标签是allowed to be self-closing

因为&lt;script&gt; 不是无效的(它可能 有内容)并且不是外来的(如MathML 或SVG),所以&lt;script&gt; 不能自封闭,无论你如何使用它。

但是为什么呢?难道他们不能把它当作外国的,做特殊情况,什么的?

HTML 5 旨在成为具有 HTML 4 和 XHTML 1 的实现backward-compatible。 它不是基于 SGML 或 XML;它的语法主要涉及记录和统一实现。 (这就是为什么 &lt;br/&gt; &lt;hr/&gt; 等是 valid HTML 5 尽管 HTML4 无效。)

自动关闭&lt;script&gt; 是实现不同的标签之一。 它used to work in Chrome, Safariand Opera;据我所知,它从未在 Internet Explorer 或 Firefox 中运行过。

This was discussed 当 HTML 5 被起草并被拒绝时,因为它 breaks browser compatibility。 自关闭脚本标签的网页可能无法在旧浏览器中正确呈现(如果有的话)。 有other proposals,但也解决不了兼容性问题。

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

自关闭 &lt;script&gt; 在 HTML 5 中不会发生,因为它向后兼容 HTML 4 和 XHTML 1。


XHTML 1 / XHTML 5

真正充当 XHTML 时,&lt;script/&gt; 真的是关闭的,正如other answers 所说的那样。

除了 the spec says应该在作为 HTML 服务时可以工作:

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

那么,发生了什么?

asked Mozillalet Firefox parse 符合 XHTML 的文档,而不管指定的内容标题(称为 content sniffing)。 无论如何,这将允许自动关闭脚本和内容嗅探was necessary,因为网络托管商还不够成熟,无法提供正确的标头; IE 是good at it

如果first browser war 没有以 IE 6 结尾,那么 XHTML 可能也在列表中。但它确实结束了。以及带有 XHTML 的 IE 6 has a problem。 事实上 IE did not support 是正确的 MIME 类型 at all,迫使 每个人text/html 用于 XHTML,因为 IE 持有 major market share 整整十年。

还有内容嗅探can bereally bad和人们说it should be stopped

最后,W3C 的didn't mean XHTML to be sniffable: 文档是,HTML 和XHTML,和Content-Type 的规则。 可以说他们坚定地坚持“按照我们的规范”和ignoring what was practicalcontinued 到更高版本的 XHTML 中的错误。

无论如何,这个决定settled the matter 用于 Firefox。 比 Chrome was born 早了 7 年;没有其他重要的浏览器。就这样决定了。

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

【讨论】:

  • @AndyE 在写自关闭
  • @AndyE:您所描述的是前向兼容性——旧代码与新编译器/解释器/解析器一起工作的能力。向后兼容性是新代码与旧编译器/解释器/解析器一起工作的能力。所以,是的,向后兼容性是个问题,否则按照新规范编写的页面将无法在旧浏览器中运行(是的,尝试让新代码尽可能在旧浏览器中运行是 Web 编程的传统)。
  • @Dmitry 现实情况是,禁止自封闭脚本是一条单向之路。如linked,自关闭
  • 非常被低估的答案
  • 一点更正:在 HTML 中显示为自封闭的标签不是带有 optional 结束标签的标签,而是带有 prohibited 的标签结束标签(空或无效标签)。带有 optional 结束标签的标签,如 &lt;p&gt;&lt;li&gt;,不能“自我关闭”,因为它们可以有内容,所以像 &lt;p/&gt; 这样的代码只不过是一个(格式错误的)开始标签和它后面的内容,如果它被允许在这个元素中,最终会在它里面。
【解决方案4】:

如果有人好奇,归根结底是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 编写代码时,它会让您陷入困境。

【讨论】:

  • 我很好奇。为什么浏览器会选择这样解释?
  • @AhmedAeonAxan:P 元素不能包含DIV 元素(这是无效的 HTML),因此浏览器隐式 关闭了P 元素(定义为“隐式关闭") 在打开 DIV 标记之前。然而,浏览器在这方面的行为往往有所不同(因为它们可以处理任何无效的 HTML)。
  • @ColeJohnson 不,这不是标签汤; greim 混淆了有效和无效 HTML 之间的界限。当作者不关心规则时,你会得到标签汤,因为浏览器使用纠错。另一方面,缺少的 &lt;/p&gt; 结束标记实际上是 HTML 定义的一部分!
  • @MrLister - 有点。 “标签汤”描述了 HTML 是如何被解析的,而不是它是如何创作的。这是一个术语,用于描述浏览器用来理解 HTML 的不同策略,与严格的 XML 解析形成对比。 XML 解析只允许用于 XML mime 类型,但由于这些类型从未得到广泛使用,浏览器退回到各种“标签汤”方案,即使对于其他有效的文档也是如此。
  • HTML5 实际上是standardized 'tag soup' 的解析,包括处理无效标记的一致方式。在那之前,浏览器不得不自己弄清楚如何处理无效标记,从而导致不一致。当前浏览器中的 HTML 解析器是有史以来最先进的软件之一。速度极快,可以处理大多数输入,产生一致的结果。
【解决方案5】:

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

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

【讨论】:

  • "IE 不支持 XHTML 解析。"在撰写本文时适用于 IE 版本,但不再适用。
  • @EricLaw 你能澄清哪个版本的 IE 修复了这个问题吗? (以及任何特定条件 - 例如需要有效的文档类型)
  • @sgunliffe IE9 是第一个完全支持 XHTML 的版本。 blogs.msdn.com/b/ie/archive/2010/11/01/…
【解决方案6】:

上面的人已经对这个问题进行了非常多的解释,但是有一点可以说清楚的是,尽管人们在 HTML 文档中一直使用&lt;br/&gt; 之类的东西,但任何处于这种位置的/ 基本上都是被忽略,并且仅在尝试使某些内容既可解析为 XML 和 HTML 时使用。例如,试试&lt;p/&gt;foo&lt;/p&gt;,你会得到一个常规段落。

【讨论】:

    【解决方案7】:

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

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

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

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

    【讨论】:

    • 我喜欢这样,但为什么它不“聪明”?
    • 因为有一个预定义的脚本标签来执行加载脚本的工作。你为什么要用别的东西来混淆事情呢?锤子敲钉子……穿鞋会不会很聪明?
    • @daveL - 我们有 &lt;style&gt; 标签,但对外部 CSS 文件使用链接标签。链接标签的定义: 标签定义了文档和外部资源之间的链接。” 链接标签用于外部 CSS 或 JS 似乎完全合乎逻辑……也就是说它的用途...链接外部文件。 注意我不是在谈论规范/跨浏览器/等等,我只是在评论使用链接标签来引入 CSS 和 JS 的逻辑性质......它实际上会带来很多如果是这样的话,那是有道理的。不确定鞋子 [类比] 是否合适。
    【解决方案8】:

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

    正如&lt;script defer&gt; 被视为&lt;script defer="defer"&gt;&lt;script /&gt; 被视为&lt;script /="/"&gt;

    【讨论】:

    • 这个解释虽然优雅,但实际上是错误的。如果它是真的,那么 DOM 中的 script 元素会有一个“/”属性。我检查过 IE、Firefox 和 Opera,它们都没有真正包含这样的属性。
    • / 不是有效的属性名称字符,因此被丢弃。否则这个解释就很清楚了。
    • 实际上,一些 HTML 解析器(尤其是验证器)可能会将 / 解释为 NET(Null End Tag)构造的一部分。
    【解决方案9】:

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

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

    IE9 和更高版本的support XHTML 5application/xhtml+xml 一起使用。

    【讨论】:

    【解决方案10】:

    那是因为 SCRIPT TAG 不是 VOID ELEMENT。

    HTML 文档中 - 无效元素 根本不需要“结束标记”!

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

    然而,脚本元素绝不是 void 或参数元素,因为 脚本标签首先是浏览器指令,而不是数据描述声明。

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

    &lt;H1&gt; 语义不能被随后的&lt;P&gt; 终止,因为它自身的语义不足以覆盖并因此终止先前的 H1 指令集。尽管它能够将 分解为新的段落行,但它还不足以覆盖当前的字体大小和样式行高向下流,即从 H1 泄漏(因为 P 没有它)。

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

    &lt; /&gt; 这样的通用no-description 终止标记足以应对遇到的级联的任何单个跌落,例如:&lt;H1&gt;Title&lt; /&gt; 但情况并非总是如此,因为我们还想要为了能够“嵌套”,流的多个中间标记:在包裹/落入另一个级联之前分成种子。因此,诸如&lt; /&gt; 之类的通用终止符将无法确定要终止的属性的目标。例如:&lt;b&gt;bold &lt;i&gt;bold-italic &lt; /&gt; italic &lt;/&gt;normal。毫无疑问,我们的意图是不正确的,并且很可能会将其解释为 bold bold-italic bold 正常。

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

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

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

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

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

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

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

    传递信息。

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

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

    【讨论】:

    • 我认为 HTML 的目的是将数据流式传输到一个代理(通常是浏览器),一个热的人。
    【解决方案11】:

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

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

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

    【讨论】:

    • 如果给出了 src 属性就没有意义。但我想它使 HTML 更容易解析。
    【解决方案12】:

    'true XHTML'、'faux XHTML' 和 HTML 之间的区别以及服务器发送的 MIME 类型的重要性是already described here well。如果您想立即尝试,这里有一个简单的可编辑 sn-p,带有实时预览,包括适用于功能强大的浏览器的自关闭脚本标签:

    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!

    对于无法使用的浏览器,您可以复制 textarea 的内容并将其保存为扩展名为 .xhtml(或 .xht)的文件 (thanks Alek for this hint)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      • 2020-12-14
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2017-09-20
      相关资源
      最近更新 更多