it-swarm-ru.tech

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

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

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

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

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

Это нарушает концепцию поддержки XHTML?

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

1247
dimarzionist

Спецификация XHTML 1 гласит:

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

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

XHTML DTD определяет элементы сценария как:

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

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

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

От w :

Таким образом, "application/xhtml + xml" ДОЛЖЕН использоваться для документов семейства XHTML, а использование "text/html" ДОЛЖНО быть ограничено HTML-совместимыми документами XHTML 1.0. "application/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 или документом внутри вашего документа - Firefox разветвляется после того, как получает заголовок text/html, который определяет, будет ли парсер HTML или XML выглядеть внутри документа, а парсер HTML - нет. понять <script />.

225
joelhardi

В случае, если кому-то интересно, окончательная причина в том, что HTML изначально был диалектом SGML, который является странным старшим братом XML. В земле SGML элементы могут быть определены в DTD как самозакрывающиеся (например, BR, HR, INPUT), неявно закрываемые (например, P, LI, TD) или явно закрываемые (например, TABLE, DIV, SCRIPT). XML, конечно, не имеет понятия об этом.

Парсеры тег-супа, используемые современными браузерами, развились из этого наследия, хотя их модель синтаксического анализа больше не является чистым SGML. И, конечно, ваш тщательно созданный XHTML рассматривается как плохо написанный SGML-вдохновленный тег-суп, если вы не отправите его с типом mime XML. Это также почему ...

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

... интерпретируется браузером как:

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

... что является рецептом для милой неясной ошибки, которая может привести вас в ярость, когда вы пытаетесь кодировать против DOM.

150
greim

Другие ответили "как" и процитировали спец. Вот реальная история "почему нет <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, который придумал этот хак , чтобы помочь перейти на XHTML, сделав его HTML-совместимым .

И конечный тег <script>не обязательно .

Тег "Самозавершающийся" является взломом в 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 to разрешить 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 родился ; не было другого значимого браузера. Так было решено.

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

139
Sheepy

Internet Explorer 8 и более ранние версии не поддерживают синтаксический анализ XHTML. Даже если вы используете декларацию XML и/или тип документа XHTML, старый IE все равно анализирует документ как обычный HTML. А в простом HTML самозакрывающийся синтаксис не поддерживается. Конечная косая черта просто игнорируется, вы должны использовать явный закрывающий тег.

Даже браузеры с поддержкой синтаксического анализа XHTML, такие как IE 9 и более поздние версии , все равно будут анализировать документ как HTML, если вы не предоставите документ с типом содержимого XML. Но в этом случае старый IE не будет отображать документ вообще!

44
JacquesB

Вышеупомянутые люди уже в значительной степени объяснили эту проблему, но одна вещь, которая может прояснить ситуацию, заключается в том, что, хотя люди используют <br/> и так всегда в HTML-документах, любой / в такой позиции в основном игнорируется и используется только при попытке сделать что-то как разбираемое как XML и HTML. Попробуйте, например, <p/>foo</p>, и вы получите обычный абзац.

26
Marijn

Самозакрывающийся тег сценария не будет работать, поскольку тег сценария может содержать встроенный код, а HTML недостаточно умен, чтобы включать или отключать эту функцию в зависимости от наличия атрибута.

С другой стороны, HTML имеет отличный тег для включения ссылок на внешние ресурсы: тег <link>, и он может быть самозакрывающимся. Он уже используется для включения таблиц стилей, каналов RSS и Atom, канонических URI и всех других вкусностей. Почему не JavaScript?

Если вы хотите, чтобы тег script был самодостаточным, вы не можете сделать это, как я сказал, но есть альтернатива, хотя и не разумная. Вы можете использовать самозакрывающийся тег link и ссылку на свой JavaScript, задав ему тип text/javascript и rel as script, что-то вроде ниже:

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

В отличие от XML и XHTML, HTML не знает самозакрывающегося синтаксиса. Браузеры, которые интерпретируют XHTML как HTML, не знают, что символ / указывает на то, что тег должен быть самозакрывающимся; вместо этого они интерпретируют его как пустой атрибут, и синтаксический анализатор все еще думает, что тег является "открытым".

Так же, как <script defer> рассматривается как <script defer="defer">, <script /> обрабатывается как <script /="/">.

20
rpetrich

Internet Explorer 8 и старше не поддерживает правильный тип MIME для XHTML, application/xhtml+xml. Если вы используете XHTML как text/html, который требуется для того, чтобы эти старые версии Internet Explorer могли что-либо делать, он будет интерпретирован как HTML 4.01. Вы можете использовать только короткий синтаксис с любым элементом, который разрешает пропуск закрывающего тега. См. спецификация HTML 4.01 .

"Краткая форма" XML интерпретируется как атрибут с именем /, который (из-за отсутствия знака равенства) интерпретируется как имеющий неявное значение "/". Это абсолютно неправильно в HTML 4.01 - необъявленные атрибуты запрещены, но браузеры игнорируют это.

IE9 и более поздние поддержка XHTML 5 подается с application/xhtml+xml.

18
Mike Dimmick

Это потому, что TAG СЦЕНАРИЙ не является пустым элементом.

В HTML-документе - VOID ELEMENTS не вообще нужен "закрывающий тег"!

В xhtml все является универсальным, поэтому им всем нужно завершение например. "закрывающий тег"; Включая br, простой разрыв строки, как <br></br> или его сокращение <br />.

Однако элемент Script никогда не является пустым или параметрическим элементом, поскольку тег сценария , прежде всего, является инструкцией браузера, а не объявлением описания данных.

В принципе, инструкция семантического завершения, например "закрывающий тег", необходима только для обработки инструкций, семантика которых не может быть завершена последующим тегом. Например:

Семантика <H1> не может быть прервана следующим <P>, потому что она не несет достаточно своей собственной семантики, чтобы переопределить и, следовательно, завершить предыдущий набор команд H1. Хотя он сможет разбить stream на новую строку абзаца, он недостаточно "силен", чтобы переопределить текущий размер шрифта и стиль line-height заливки вниз по течению , т.е. вытекает из H1 (потому что у P его нет).

Вот как и почему была изобретена сигнализация "/" (завершение).

Универсальный тег завершения без описания , такой как < />, был бы достаточен для любого отдельного падения встречного каскада, например: <H1>Title< />, но это не всегда так, потому что мы также хотим иметь возможность "вложения", множественные промежуточные теги потока: разделить на потоки перед упаковкой/падением на другой каскад. Как следствие, общий терминатор, такой как < />, не сможет определить цель свойства для завершения. Например: <b>полужирный<i> полужирный курсив < /> курсив </>normal. Несомненно, не сможет правильно понять наше намерение и, скорее всего, будет интерпретировать его как полужирный полужирный полужирный нормальный.

Так родился понятие обертки, т. Е. Контейнера. (Эти понятия настолько похожи, что их невозможно различить, и иногда один и тот же элемент может иметь и то и другое. <H1> одновременно является и оболочкой, и контейнером. Тогда как <B> только семантическая оболочка). Нам понадобится простой контейнер без семантики. И, конечно, изобретение элемента DIV появилось.

Элемент DIV на самом деле является 2BR-контейнером. Конечно, появление CSS сделало всю ситуацию более странной, чем могло бы быть, и вызвало большую путаницу со многими великими последствиями - косвенно!

Поскольку с помощью CSS вы можете легко переопределить нативное поведение до и после BR недавно изобретенного DIV, его часто называют "контейнером бездействия". Что, естественно, неправильно! DIVs являются блочными элементами и будут изначально прерывать линию потока как до, так и после сигнализации окончания. Вскоре в сети начали страдать страницы DIV-itis. Большинство из них до сих пор.

Появление CSS с его способностью полностью переопределить и полностью переопределить нативное поведение любого HTML-тега, каким-то образом сумело запутать и затуманить весь смысл существования HTML ...

Внезапно все HTML-теги выглядели как устаревшие, они были испорчены, лишены всего их первоначального значения, идентичности и цели. Каким-то образом у вас сложится впечатление, что они больше не нужны. Говоря: одного тега контейнера-обертки будет достаточно для всего представления данных. Просто добавьте необходимые атрибуты. Почему бы не иметь значимые теги вместо этого; Придумайте имена тегов по мере необходимости и позвольте CSS возиться с остальными.

Вот как родился xhtml и, конечно, великий тупой, столь дорого заплативший новичкам и искаженное видение того, что к чему, и какова чертова цель всего этого. W3C перешел из World Wide Web в "Что пошло не так, товарищи?"

Назначение HTML - для потоковой передачи значимых данных для человека-получателя.

Для доставки информации.

Формальная часть предназначена только для обеспечения ясности доставки информации. xhtml не дает ни малейшего рассмотрения информации. - Для него информация абсолютно неактуальна.

Самое главное в этом вопросе - знать и понимать, что xhtml - это не просто версия какого-то расширенного HTML, xhtml - это совершенно другой зверь; обосновывается; и поэтому разумно держать их отдельно.

5
Bekim Bacaj

Разница между 'true XHTML', 'faux XHTML' и HTML, а также важность MIME-типа, отправляемого сервером, была здесь уже хорошо описано . Если вы хотите попробовать это прямо сейчас, вот простой редактируемый фрагмент с предварительным просмотром в реальном времени, включая самозакрывающийся тег сценария для браузеров с поддержкой:

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) ( спасибо Алеку за этот совет ).

2
myf