Вопрос: Почему самозакрывающиеся скриптовые теги не работают?


Какова причина, по которой браузеры неправильно распознают:

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

Только это признано:

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

Разве это нарушает концепцию поддержки XHTML?

Примечание. Это утверждение является правильным, по крайней мере, для всех IE (6-8 бета 2).


1138


источник


Ответы:


Спецификация XHTML 1 говорит:

С.3. Элемент Минимизация и содержание пустого элемента

Учитывая пустой экземпляр элемента, модель содержимого которого не является EMPTY(например, пустой заголовок или абзац) не используют минимизированную форму (например, использование <p> </p>и не <p />).

XHTML DTD определяет теги скриптов как:

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

410



Чтобы добавить к тому, что сказал Брэд и squadette, самозакрывающийся синтаксис XML <script />на самом деле является правильный XML, но для того, чтобы он работал на практике, вашему веб-серверу также необходимо отправить ваши документы как правильно сформированные XML с помощью XML-типа mimetype, например application/xhtml+xmlв заголовке HTTP Content-Type (и не в виде text/html).

Однако отправка XML-mimetype приведет к тому, что ваши страницы не будут анализироваться IE7, которым нравится только text/html,

Из w3 :

Таким образом, «application / xhtml + xml»   СЛЕДУЕТ использовать для семьи XHTML   документы и использование «text / html»   ДОЛЖЕН быть ограничен HTML-совместимым   XHTML 1.0 документы. 'Приложение / XML'   и 'text / xml' МОЖЕТ также использоваться, но   когда это необходимо,   'application / xhtml + xml' ДОЛЖНО использоваться   а не общий носитель XML   типы.

Я несколько озадачился этим несколько месяцев назад, и единственным работоспособным (совместимым с FF3 + и IE7) решением было использование старого <script></script>синтаксис с text/html(Синтаксис HTML + mimetype HTML).

Если ваш сервер отправляет text/htmlвведите в свои HTTP-заголовки, даже если в противном случае правильно сформированные документы XHTML, FF3 + будет использовать свой режим рендеринга HTML, что означает, что <script />не будет работать (это изменение, Firefox ранее был менее строгим).

Это произойдет независимо от того, http-equivметатеги, пролог XML или doctype внутри вашего документа - ветви Firefox, когда он получает text/htmlзаголовок, который определяет, выглядит ли парсер HTML или XML внутри документа, а парсер HTML не понимает <script />,


210



В случае, если кому-то интересно, конечной причиной является то, что HTML изначально был диалектом SGML, который является странным старшим братом XML. В SGML-зоне теги могут быть указаны в 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.


138



Другие ответили «как» и цитировали спецификацию. Вот реальная история «почему нет <script/>», после многих часов перекопав в отчеты об ошибках и списки рассылки.


HTML 4

HTML 4 основан на SGML ,

SGML имеет некоторые shorttags , такие как <BR//, <B>text</>, <B/text/, или <OL<LI>item</LI</OL>, XML принимает первую форму, переопределяет окончание как «>» (SGML является гибким), так что он становится <BR/>,

Однако HTML не изменился, поэтому <SCRIPT/> должен имею в виду <SCRIPT>>,
(Да, '>' должен быть частью контента, а тег по-прежнему не закрыто.)

Очевидно, что это несовместимо с XHTML и будем ломать многие сайты (к тому времени, когда браузеры были достаточно зрелыми беспокоиться об этом ), так никто не применял шорттаг и спецификация советует им ,

Фактически все «рабочие» самозаверяющие теги являются тегами с дополнительным концевым тегом на технически несоответствующих синтаксических анализаторах и фактически недействительны. Это был W3C, который придумал этот хак чтобы помочь перейти на XHTML, сделав это HTML-совместимый ,

А также <script>Конечный тег необязательный ,

Тег «Self-End» - это взломать HTML 4 и не имеет смысла.


HTML 5

HTML5 имеет пять типов тегов и только теги «void» и «foreign» допускается самозакрывание ,

Потому как <script>не является недействительным (это май имеют контент) и не являются иностранными (например, MathML или SVG), <script>не может быть самозакрытым, независимо от того, как вы его используете.

Но почему? Разве они не могут считать это чужими, делать особый случай или что-то еще?

HTML 5 направлен на то, чтобы обратная совместимость с реализации HTML 4 и XHTML 1. Он не основан на SGML или XML; его синтаксис в основном связан с документированием и объединением реализаций. (Вот почему <br/> <hr/>и т.д. действительный HTML 5 несмотря на то, что он недействителен HTML4.)

Самозамыкающийся <script>является одним из тегов, где реализации различаются. Это используется для работы в Chrome, Safari , и Opera ; Насколько мне известно, он никогда не работал в Internet Explorer или Firefox.

Это обсуждалось когда HTML 5 был составлен и получил отказ, потому что он брейки браузер совместимость , Веб-страницы, которые автоматически закрывают тег скрипта, могут отображаться неправильно (если вообще) в старых браузерах. Были другие предложения , но они также не могут решить проблему совместимости.

После того, как проект был выпущен, WebKit обновил парсер, чтобы он соответствовал.

Самозамыкающийся <script>не происходит в HTML 5 из-за обратной совместимости с HTML 4 и XHTML 1.


XHTML 1 / XHTML 5

когда действительно служил XHTML, <script/>действительно закрыта, поскольку другие ответы записано.

Кроме этого спецификация говорит Это должен работали, когда служили HTML:

Документы XHTML ... могут быть помечены типом интернет-медиа «text / html» [RFC2854], поскольку они совместимы с большинством браузеров HTML.

Итак, что случилось?

люди спросил Mozilla в пусть анализирует Firefox соответствующих документов в качестве XHTML независимо от указанного заголовка содержимого (известного как контентное обнюхивание ). Это позволило бы самозакрывающиеся скрипты и обнюхивание контента было необходимо так или иначе, потому что веб-хостеры недостаточно зрелы, чтобы обслуживать правильный заголовок; IE был хорош в этом ,

Если первая война в браузере не закончился с IE 6, XHTML, возможно, тоже был в списке. Но все закончилось. И IE 6 имеет проблему с XHTML. Фактически IE не поддерживал правильный тип MIME вообще , принуждение все использовать text/htmlдля XHTML, потому что IE имела значительную долю на рынке в течение целого десятилетия.

А также контентное обнюхивание возможно действительно плохо и люди говорят его следует остановить ,

Наконец, оказывается, что W3C не означало, что XHTML был бы нюхательным : документ и то и другое , HTML и XHTML, и Content-Typeправила. Можно сказать, что они твердо стояли на «просто следуйте нашей спецификации» и игнорируя то, что было практично , Ошибка, которая продолжение в более поздние версии XHTML.

В любом случае, это решение урегулировал вопрос для Firefox. Это было за 7 лет до Chrome родился ; не было другого значительного браузера. Таким образом, было решено.

Указание только одного doctype не приводит к синтаксическому анализу XML из-за следующих спецификаций.


121



Internet Explorer 8 and earlier do not support XHTML parsing. Even if you use an XML declaration and/or an XHTML doctype, old IE still parse the document as plain HTML. And in plain HTML, the self-closing syntax is not supported. The trailing slash is just ignored, you have to use an explicit closing tag.

Even browsers with support for XHTML parsing, such as IE 9 and later, will still parse the document as HTML unless you serve the document with a XML content type. But in that case old IE will not display the document at all!


43



The people above have already pretty much explained the issue, but one thing that might make things clear is that, though people use '&lt;br/>' and such all the time in HTML documents, any '/' in such a position is basically ignored, and only used when trying to make something both parseable as XML and HTML. Try '&lt;p/>foo&lt;/p>', for example, and you get a regular paragraph.


25



The self closing script tag won't work, because the script tag can contain inline code, and HTML is not smart enough to turn on or off that feature based on the presence of an attribute.

On the other hand, HTML does have an excellent tag for including references to outside resources: the <link> tag, and it can be self-closing. It's already used to include stylesheets, RSS and Atom feeds, canonical URIs, and all sorts of other goodies. Why not JavaScript?

If you want the script tag to be self enclosed you can't do that as I said, but there is an alternative, though not a smart one. You can use the self closing link tag and link to your JavaScript by giving it a type of text/javascript and rel as script, something like below:

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

23



Unlike XML and XHTML, HTML has no knowledge of the self-closing syntax. Browsers that interpret XHTML as HTML don't know that the / character indicates that the tag should be self-closing; instead they interpret it like an empty attribute and the parser still thinks the tag is 'open'.

Just as <script defer> is treated as <script defer="defer">, <script /> is treated as <script /="/">.


19



Internet Explorer 8 and older don't support the proper MIME type for XHTML, application/xhtml+xml. If you're serving XHTML as text/html, which you have to for these older versions of Internet Explorer to do anything, it will be interpreted as HTML 4.01. You can only use the short syntax with any element that permits the closing tag to be omitted. See the HTML 4.01 Specification.

The XML 'short form' is interpreted as an attribute named /, which (because there is no equals sign) is interpreted as having an implicit value of "/". This is strictly wrong in HTML 4.01 - undeclared attributes are not permitted - but browsers will ignore it.

IE9 and later support XHTML 5 served with application/xhtml+xml.


18



Difference between 'true XHTML', 'faux XHTML' and HTML as well as importance of the server-sent MIME type had been already described here well. If you want to try it out right now, here is simple editable snippet with live preview including self-closed script tag for capable browsers:

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>

You should see Hello, true XHTML. Nice to meet you! below textarea.

For incapable browsers you can copy content of the textarea and save it as a file with .xhtml (or .xht) extension (thanks Alek for this hint).


3



That's because SCRIPT TAG is not a VOID ELEMENT.

In an HTML Document - VOID ELEMENTS do not need a "closing tag" at all!

In xhtml, everything is Generic, therefore they all need termination e.g. a "closing tag"; Including br, a simple line-break, as <br></br> or its shorthand <br />.

However, a Script Element is never a void or a parametric Element, because script tag before anything else, is a Browser Instruction, not a Data Description declaration.

Principally, a Semantic Termination Instruction e.g., a "closing tag" is only needed for processing instructions who's semantics cannot be terminated by a succeeding tag. For instance:

<H1> semantics cannot be terminated by a following <P> because it doesn't carry enough of its own semantics to override and therefore terminate the previous H1 instruction set. Although it will be able to break the stream into a new paragraph line, it is not "strong enough" to override the present font size & style line-height pouring down the stream, i.e leaking from H1 (because P doesn't have it).

This is how and why the "/" (termination) signalling has been invented.

A generic no-description termination Tag like < />, would have sufficed for any single fall off the encountered cascade, e.g.: <H1>Title< /> but that's not always the case, because we also want to be capable of "nesting", multiple intermediary tagging of the Stream: split into torrents before wrapping / falling onto another cascade. As a consequence a generic terminator such as < /> would not be able to determine the target of a property to terminate. For example: <b>bold <i>bold-italic < /> italic </>normal. Would undoubtedly fail to get our intention right and would most probably interpret it as bold bold-itallic bold normal.

This is how the notion of a wrapper ie., container was born. (These notions are so similar that it is impossible to discern and sometimes the same element may have both. <H1> is both wrapper and container at the same time. Whereas <B> only a semantic wrapper). We'll need a plain, no semantics container. And of course the invention of a DIV Element came by.

The DIV element is actually a 2BR-Container. Of course the coming of CSS made the whole situation weirder than it would otherwise have been and caused a great confusion with many great consequences - indirectly!

Because with CSS you could easily override the native pre&after BR behavior of a newly invented DIV, it is often referred to, as a "do nothing container". Which is, naturally wrong! DIVs are block elements and will natively break the line of the stream both before and after the end signalling. Soon the WEB started suffering from page DIV-itis. Most of them still are.

The coming of CSS with its capability to fully override and completely redefine the native behavior of any HTML Tag, somehow managed to confuse and blur the whole meaning of HTML existence...

Suddenly all HTML tags appeared as if obsolete, they were defaced, stripped of all their original meaning, identity and purpose. Somehow you'd gain the impression that they're no longer needed. Saying: A single container-wrapper tag would suffice for all the data presentation. Just add the required attributes. Why not have meaningful tags instead; Invent tag names as you go and let the CSS bother with the rest.

This is how xhtml was born and of course the great blunt, paid so dearly by new comers and a distorted vision of what is what, and what's the damn purpose of it all. W3C went from World Wide Web to What Went Wrong, Comrades?!!

The purpose of HTML is to stream meaningful data to the human recipient.

To deliver Information.

The formal part is there to only assist the clarity of information delivery. xhtml doesn't give the slightest consideration to the information. - To it, the information is absolutely irrelevant.

The most important thing in the matter is to know and be able to understand that xhtml is not just a version of some extended HTML, xhtml is a completely different beast; grounds up; and therefore it is wise to keep them separate.


2