代码之家  ›  专栏  ›  技术社区  ›  dimarzionist

为什么自动关闭脚本标记不起作用?

  •  1209
  • dimarzionist  · 技术社区  · 16 年前

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

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

    只有这样才能识别:

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

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

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

    11 回复  |  直到 6 年前
        1
  •  444
  •   Nathan Tuggy TonyLuigiC    9 年前

    XHTML 1规格说明:

    С.3. Element Minimization and Empty Element Content

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

    XHTML DTD 指定脚本标记为:

    <!-- script statements, which may include CDATA sections -->
    <!ELEMENT script (#PCDATA)>
    
        2
  •  220
  •   joelhardi    16 年前

    为了增加Brad和Squadette所说的内容,可以使用自关闭的XML语法 <script /> 事实上 正确的XML,但要使其在实践中工作,您的Web服务器还需要将文档作为格式正确的XML和类似XML mimetype的XML发送。 application/xhtml+xml 在HTTP内容类型头(和 作为 text/html )

    但是,发送XML mimetype将导致IE7无法解析您的页面,而IE7只喜欢 文本/ HTML .

    w3 :

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

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

    如果服务器发送 文本/ HTML 键入其HTTP头,即使XHTML文档格式正确,ff3+也将使用其HTML呈现模式,这意味着 <脚本/gt; 将不起作用(这是一个变化,火狐以前不那么严格)。

    不管你怎么摆弄,这都会发生。 http-equiv 元标记,文档中的XML prolog或doctype——一旦获得 文本/ HTML 头,决定HTML或XML解析器是否在文档中查找,而HTML解析器不理解 <脚本/gt; .

        3
  •  145
  •   greim Claiohm    7 年前

    如果有人好奇的话,最终的原因是HTML最初是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>
    

    …这是一个可爱的、晦涩难懂的bug的配方,当您试图对DOM进行编码时,它会让您陷入困境。

        4
  •  136
  •   Community SushiHangover    7 年前

    其他人回答了“如何”并引用了规范。这里是“为什么不”的真实故事。 <script/> “,在花了很多时间研究bug报告和邮件列表之后。


    HTML 4

    HTML 4基于 SGML .

    SGML有一些 shorttags ,如 <BR// , <B>text</> , <B/text/ <OL<LI>item</LI</OL> . XML采用第一种形式,将结尾重新定义为“>”(SGML是灵活的),以便 <BR/> .

    但是,HTML没有被重新定义,所以 <SCRIPT/> should mean <SCRIPT>> .
    (是的,“>”应该是内容的一部分,标记仍然是 关闭的)

    显然,这与XHTML不兼容,并且 打破许多网站(当浏览器足够成熟时 to care about this 如此 nobody implemented shorttags 以及规格 advises against them .

    实际上,所有“工作”的自结束标记在技术上不一致的解析器上都是带有可选结束标记的标记,实际上是无效的。 是W3C came up with this hack 通过创建XHTML来帮助转换为XHTML HTML-compatible .

    <script> 的结束标记是 not optional .

    “self-ending”标签在HTML4中是一种黑客行为,毫无意义。


    HTML 5

    HTML5 five types of tags 只有“作废”和“外国”标签 allowed to be self-closing .

    因为 <脚本& GT; 不是空虚(它) 可以 有内容)并且不是外来的(如mathml或svg)。 <脚本& GT; 无论您如何使用,都不能自动关闭。

    但是为什么呢?难道他们不能把它看作是外来的、特例的或是什么吗?

    HTML 5的目标是 backward-compatible 具有 实现方式 HTML 4和XHTML 1。 它不是基于SGML或XML的;它的语法主要与实现的文档化和统一有关。 (这就是为什么 <br/> <hr/> 等是 valid HTML 5 尽管HTML4无效。)

    自动关闭 <脚本& GT; 是用于实现不同的标记之一。 它 used to work in Chrome, Safari , and Opera 据我所知,它从未在Internet Explorer或Firefox中工作过。

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

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

    自动关闭 <脚本& GT; 在HTML5中不会发生,因为它与HTML4和XHTML 1向后兼容。


    XHTML 1/XHTML 5

    什么时候? 真的? 作为XHTML, <脚本/gt; 非常封闭,如 other answers 陈述过。

    除了那个 the spec says 应该 作为HTML使用时有效:

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

    那么,发生了什么?

    asked Mozilla let Firefox parse 合格文件 XHTML 无论指定的内容头(称为 content sniffing ) 这将允许自动关闭脚本和内容嗅探 was necessary 不管怎样,因为网络主机还不够成熟,不能提供正确的报头;即 good at it .

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

    还有内容嗅探 can be really bad 人们都在说 it should be stopped .

    最后,结果是W3C didn't mean XHTML to be sniffable :文档是 二者都 ,HTML和XHTML,以及 Content-Type 规则。 可以说,他们是坚定地站在“只要遵守我们的规范”和 ignoring what was practical . 一个错误 continued 到后来的XHTML版本。

    不管怎样,这个决定 settled the matter 对于火狐。 7年前铬 was born 没有其他重要的浏览器。于是决定了。

    由于以下规范,仅指定doctype不会触发XML分析。

        5
  •  44
  •   Damian Yerrick    9 年前

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

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

        6
  •  26
  •   sg7 Krafty Coder    6 年前

    上面的人已经很好地解释了这个问题,但是有一件事可以让事情变得清楚,尽管人们使用 '&lt;br/>' 一直这样 HTML 任何文件 '/' 在这种情况下,基本上是被忽略的,并且只在试图使某个东西同时被解析为 XML HTML . 尝试 '&lt;p/>foo&lt;/p>' 例如,你会得到一个普通的段落。

        7
  •  23
  •   user2428118    10 年前

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

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

    如果您希望脚本标记是自封闭的,那么您不能像我所说的那样做,但是有一个可选的,尽管不是智能的。您可以使用自动关闭的链接标记,并通过将文本/javascript和rel类型作为脚本链接到您的javascript,如下所示:

    <link type="text/javascript" rel ="script" href="/path/tp/javascript" />
    
        8
  •  20
  •   Sebastian Zartner Emmanouil Chountasis    9 年前

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

    正如 <script defer> 被视为 <script defer="defer"> , <script /> 被视为 <script /="/"> .

        9
  •  19
  •   Mike Dimmick    9 年前

    Internet Explorer 8及更高版本不支持XHTML的正确MIME类型, application/xhtml+xml . 如果您将XHTML作为 text/html 如果要让这些旧版本的Internet Explorer执行任何操作,它将被解释为HTML 4.01。您只能对允许省略结束标记的任何元素使用短语法。见 HTML 4.01 Specification .

    XML“short form”被解释为名为/的属性,该属性(因为没有等号)被解释为隐式值为“/”。这在HTML4.01中是完全错误的-不允许使用未声明的属性-但是浏览器会忽略它。

    IE9及以后 support XHTML 5 服侍 应用程序/xhtml+xml .

        10
  •  5
  •   Bekim Bacaj    7 年前

    这是因为脚本标记不是空元素。

    在一个 HTML文档 空隙元素 需要一个“结束标签”!

    XHTML ,所有东西都是通用的,因此它们都需要 终止 例如,“结束标记”;包括br,简单的换行符,如 <br></br> 或其 速记 <br /> .

    但是,脚本元素绝不是空元素或参数元素,因为 脚本标记 除此之外,还有一条浏览器指令,而不是数据描述声明。

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

    <H1> 语义不能由以下内容终止 <P> 因为它没有足够的语义来覆盖和终止之前的h1指令集。虽然它能打破 流动 在新的段落行中,它的强度不足以覆盖当前的字体大小和样式行高度。 倒流 ,即从h1泄漏(因为p没有)。

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

    通用的 没有描述 终端标签 < /> 对于任何一次从遇到的梯级上坠落都是足够的,例如: <H1>Title< /> 但情况并非总是如此,因为我们还希望能够“嵌套”,对流进行多个中间标记:在包装/落入另一个级联之前,将其拆分为流。因此,通用终结符 </gt; 无法确定要终止的属性的目标。例如: <b> 大胆的 <i> 粗斜体字 </gt; 斜体字 </> 正常的。毫无疑问,我们的意图是不正确的,最可能解释为 大胆的 粗斜体 大胆的 正常的。

    这就是如何 概念 容器的诞生。(这些概念如此相似,以至于无法辨别,有时相同的元素可能两者都有。 <H1gt; 同时是包装器和容器。反之 <B> 只有语义包装器)。我们需要一个简单的,没有语义的容器。当然,一个DIV元素的发明是由它引起的。

    DIV元素实际上是一个2BR容器。当然,CSS的出现使整个情况比原本的情况更为奇怪,并导致了巨大的混乱,并产生了许多巨大的后果——间接的!

    因为有了CSS,您可以很容易地覆盖一个新发明的DIV的本机pre&after-br行为,它通常被称为“不做任何事情的容器”。这当然是错误的!div是块元素,在结束信号发送之前和之后都会本地中断流的行。很快,网络就开始遭受页面分割的痛苦。他们中的大多数仍然是。

    CSS的出现及其完全重写和重新定义任何HTML标记的本机行为的能力,以某种方式设法混淆和模糊了HTML存在的全部意义…

    突然间,所有的HTML标签都显得过时了,它们被破坏了,失去了所有的原始含义、身份和目的。不知怎么的,你会觉得他们不再需要了。说:一个容器包装标签就足以满足所有的数据表示。只需添加所需的属性。为什么不换个有意义的标签呢;边走边发明标签名,让CSS来处理其余的问题。

    XHTML就是这样诞生的,当然,它是一个生硬的东西,新来者付出了如此高昂的代价,它扭曲了人们对什么是什么,以及它的目的到底是什么的看法。W3C从万维网走向了哪里,同志们?!!!

    HTML的目的是 向人类接收者提供有意义的数据。

    传递信息。

    正式部分仅用于帮助信息传递的清晰性。 XHTML对这些信息没有丝毫的考虑。-对它来说,信息是完全无关的。

    最重要的是了解并能够理解 XHTML不仅仅是某些扩展HTML的一个版本 ,xhtml是一种完全不同的野兽;会搁浅;因此 把它们分开是明智的。

        11
  •  3
  •   myf    6 年前

    “true-xhtml”、“faux-xhtml”和html之间的区别以及服务器发送的mime类型的重要性是 already described here well . 如果您现在想尝试一下,这里有一个简单的可编辑片段,带有实时预览功能,包括适用于功能强大的浏览器的自关闭脚本标记:

    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 )扩展 thanks Alek for this hint )