Dlaczego samo-zamykające się elementy skryptu nie działają?

Jaki jest powód, dla którego przeglądarki nie rozpoznają poprawnie:

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

Tylko to jest rozpoznawane:

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

Czy to łamie koncepcję obsługi XHTML?

Uwaga: to stwierdzenie jest poprawne przynajmniej dla wszystkich IE (6-8 beta 2).

Author: John, 2008-09-16

12 answers

Specyfikacja XHTML 1 mówi:

С.3. Minimalizacja elementu i pusta zawartość elementu

Biorąc pod uwagę pustą instancję elementu, którego modelem zawartości nie jest EMPTY (na przykład pusty tytuł lub akapit), nie używaj minimalizowanej formy (np. użyj <p> </p>, a nie <p />).

XHTML DTD określa elementy skryptu jako:

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>
 492
Author: squadette,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-09 03:59:24

Aby dodać do tego, co powiedzieli Brad i squadette, samo-zamykająca się składnia XML <script /> w rzeczywistości jest poprawnym XML, ale aby to działało w praktyce, Twój serwer WWW musi również wysyłać dokumenty jako poprawnie uformowany XML z typem MIME XML, takim jak application/xhtml+xml w nagłówku HTTP Content-Type (i , a nie jako text/html).

Jednak wysłanie typu MIME XML spowoduje, że Twoje strony nie będą parsowane przez IE7, który tylko lubi text/html.

From w3 :

W podsumowaniu "application / xhtml+xml" Powinien być stosowany dla rodziny XHTML dokumentów, a użycie "text / html" Powinny być ograniczone do kompatybilnych z HTML Dokumenty XHTML 1.0. "application / xml" i 'text / xml' może być również używany, ale w stosownych przypadkach, należy użyć "application / xhtml+xml" zamiast tych generycznych nośników XML typy.

Zastanowiłem się nad tym kilka miesięcy temu i jedynym wykonalnym (zgodnym z FF3+ i IE7) rozwiązaniem było użycie starej składni <script></script> z text/html (składnia HTML + typ MIME HTML).

Jeśli twój serwer wyśle typ text/html w nagłówkach HTTP, nawet z odpowiednio uformowanymi dokumentami XHTML, FF3 + użyje swojego trybu renderowania HTML, co oznacza, że <script /> nie będzie działać (jest to zmiana, Firefox był wcześniej mniej rygorystyczny).

Stanie się to bez względu na manipulowanie http-equiv meta elementami, XML prolog lub doctype wewnątrz dokumentu -- Firefox branches po otrzymaniu nagłówka text/html, który określa czy parser HTML lub XML zagląda do dokumentu, a parser HTML nie rozumie <script />.

 243
Author: joelhardi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-09 03:59:38

Jeśli ktoś jest ciekawy, ostatecznym powodem jest to, że HTML był pierwotnie dialektem SGML, który jest dziwnym starszym bratem XML. W SGML-land elementy mogą być określone w DTD jako samozamykające się (np. BR, HR, INPUT), niejawnie zamykające (np. P, LI, TD) lub jawnie zamykające (np. TABLE, DIV, SCRIPT). XML, oczywiście, nie ma pojęcia o tym.

Parsery tag-soup używane przez nowoczesne przeglądarki wyewoluowały z tego dziedzictwa, chociaż ich model parsowania nie jest czystym SGML już nie. I oczywiście, twój starannie opracowany XHTML jest traktowany jako źle napisany tag-soup inspirowany SGML, chyba że wyślesz go z typem mime XML. Dlatego też...

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

...jest interpretowany przez przeglądarkę jako:

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

...czyli przepis na piękny niejasny błąd, który może rzucić cię w Passy, gdy próbujesz kodować przeciwko domowi.

 175
Author: greim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-13 03:19:43

Inni odpowiedzieli "jak" i zacytowali spec. Oto prawdziwa historia " why no <script/>", po wielu godzinach grzebania w raportach o błędach i listach dyskusyjnych.


HTML 4

HTML 4 jest oparty na SGML.

SGML ma kilka shorttagów , takich jak <BR//, <B>text</>, <B/text/, lub <OL<LI>item</LI</OL>. XML przyjmuje pierwszą formę, redefiniuje zakończenie jako " > " (SGML jest elastyczny), tak że staje się <BR/>.

Jednak HTML nie redfine, więc <SCRIPT/> powinno oznaczać <SCRIPT>>.
(Tak, ' > ' powinien być częścią treści, a znacznik nadal jest zamknięty , a nie.)

Oczywiście, jest to niezgodne z XHTML i będzie złamać wiele stron (do czasu, gdy przeglądarki były wystarczająco dojrzałe dbać o tym), więc nikt nie zaimplementował shorttagów, a specyfikacja odradza je.

Skutecznie, wszystkie 'działające' tagi są tagami z zakazanym end tag na technicznie niezgodnych parserach i są w rzeczywistości nieważne. To właśnie W3C wymyślił ten hack, aby pomóc przejść do XHTML poprzez uczynienie go kompatybilnym z HTML.

I <script> znacznik końcowy jest nie jest zabroniony .

"Tag Self-ending" jest hack w HTML 4 i jest bez znaczenia.


HTML 5

HTML5 ma pięć typów znaczników i tylko znaczniki "void" i "foreign" są dozwolone samozamykające się .

Ponieważ <script> nie jest void (it may have content) i nie jest obca (jak MathML czy SVG), <script> nie może być samozamykany, niezależnie od tego, jak go używasz.

Ale dlaczego? Nie mogą uznać tego za obce, zrobić wyjątkową sprawę,czy coś?

HTML 5 ma być wstecznie kompatybilny Z implementacjami HTML 4 i XHTML 1. Nie jest oparty na SGML czy XML. jego składnia dotyczy głównie dokumentowania i jednoczenia wdrożenia. (Dlatego <br/> <hr/> itd. czy poprawny HTML 5 pomimo niepoprawnego HTML4.)

Self-closing <script> jest jednym ze znaczników, w których implementacje się różnią. To używane do pracy w Chrome, Safari, i Opera ; według mojej wiedzy nigdy nie działała w Internet Explorerze czy Firefoksie.

To było omawiane kiedy HTML 5 był projektowany i został odrzucony, ponieważ łamie przeglądarka zgodność . Strony internetowe, których znacznik skryptu sam się zamknie, mogą nie być renderowane poprawnie (jeśli w ogóle) w starych przeglądarkach. Były inne propozycje , ale nie mogą rozwiązać problemu zgodności.

Po wydaniu szkicu, WebKit zaktualizował parser, aby był zgodny.

Samo-zamknięcie <script> nie występuje w HTML 5 ze względu na wsteczną kompatybilność z HTML 4 i XHTML 1.


XHTML 1 / XHTML 5

Kiedy naprawdę służył jako XHTML, <script/> jest naprawdę zamknięty, tak jak inne odpowiedzi stwierdziły.

Z wyjątkiem tego, że spec mówi to powinno zadziałać, gdy zostanie podane jako HTML:

Dokumenty XHTML ... mogą być oznaczone nośnikiem internetowym typu " text / html "[RFC2854] , ponieważ są one zgodne z większością przeglądarek HTML.

Co się stało?

Ludzie poprosili Mozillę aby pozwolili Firefox przetwarza zgodne dokumenty jako XHTML niezależnie od podanego nagłówka zawartości(znanego jako content sniffing ). Umożliwiłoby to samodzielne zamykanie skryptów, a sniffing treści był konieczny w każdym razie, ponieważ hosterzy nie byli wystarczająco dojrzali, aby obsługiwać poprawny nagłówek; IE był w tym dobry {27]}.

Jeśli pierwsza wojna przeglądarek nie skończyła się na IE 6, XHTML też mógł być na liście. Ale to się skończyło. I IE 6 ma problem z XHTML. W rzeczywistości IE nie obsługiwał poprawnego typu MIME w ogóle, zmuszając wszystkich do używania text/html dla XHTML, ponieważ IE posiadał duży udział w rynku przez całą dekadę.

A także sniffing treści może być naprawdę źle i ludzie mówią to powinno być powstrzymane .

W końcu okazuje się, że W3C nie oznaczało, że XHTML będzie sniffable : dokument jest zarówno , HTML i XHTML oraz Content-Type Zasady. Można powiedzieć, że stali stanowczo NA "po prostu postępuj zgodnie z naszą specyfikacją" i ignorując to, co było praktyczne. Błąd, który kontynuował w późniejszych wersjach XHTML.

W każdym razie ta decyzja rozstrzygnęła sprawę Firefoksa. To było 7 lat przed narodzinami Chrome ; nie było innej znaczącej przeglądarki. Tak więc zdecydowano.

Samo podanie doctype nie powoduje parsowania XML ze względu na następujące specyfikacje.

 171
Author: Sheepy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-23 10:04:36

Internet Explorer 8 i wcześniejsze nie obsługują parsowania XHTML. Nawet jeśli używasz deklaracji XML i/lub doctype XHTML, Stary IE nadal przetwarza dokument jako zwykły HTML. A w prostym HTML składnia samo-zamykająca się nie jest obsługiwana. Końcowy Ukośnik jest po prostu ignorowany, musisz użyć jawnego znacznika zamykającego.

Nawet przeglądarki obsługujące parsowanie XHTML, takie jak IE 9 i późniejsze , nadal będą przetwarzać dokument jako HTML, chyba że podasz dokument z typem zawartości XML. Ale w takim przypadku Stary IE w ogóle nie wyświetli dokumentu!

 44
Author: JacquesB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-05 17:10:36

Osoby powyżej już wyjaśniły ten problem, ale jedną rzeczą, która może wyjaśnić, jest to, że chociaż ludzie używają <br/> i takich przez cały czas w dokumentach HTML, Wszelkie / w takiej pozycji są w zasadzie ignorowane i używane tylko podczas próby stworzenia czegoś, co można analizować zarówno jako XML, jak i HTML. Spróbuj na przykład <p/>foo</p>, a otrzymasz zwykły akapit.

 28
Author: Marijn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-06 14:31:13

Samozamykający się znacznik skryptu nie będzie działać, ponieważ znacznik skryptu może zawierać kod wbudowany, A HTML nie jest wystarczająco inteligentny, aby włączyć lub wyłączyć tę funkcję w oparciu o obecność atrybutu.

Z drugiej strony, HTML ma doskonały tag do włączania odwołania do zasobów zewnętrznych: znacznik <link>, A może być samozamykające się. Jest już używany do dołączania arkuszy stylów, RSS i Atom kanały, kanoniczne Uri i inne gadżety. Dlaczego nie JavaScript?

Jeśli chcesz, aby znacznik script był zamknięty, nie możesz tego zrobić, jak powiedziałem, ale jest alternatywa, choć nie mądra. Możesz użyć samozamykającego się znacznika linku i linku do swojego JavaScript, nadając mu typ tekstu / javascript i rel jako skryptu, coś jak poniżej:

<link type="text/javascript" rel ="script" href="/path/tp/javascript" />
 22
Author: defau1t,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-22 08:51:03

W przeciwieństwie do XML i XHTML, HTML nie posiada wiedzy o składni samo-zamykającej się. Przeglądarki interpretujące XHTML jako HTML nie wiedzą, że znak / wskazuje, że znacznik powinien być samozamykający się; zamiast tego interpretują go jak pusty atrybut, a parser nadal myśli, że znacznik jest 'otwarty'.

Podobnie jak <script defer> jest traktowany jako <script defer="defer">, <script /> jest traktowany jako <script /="/">.

 21
Author: rpetrich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-27 11:05:22

Internet Explorer 8 i starsze nie obsługują właściwego typu MIME dla XHTML, application/xhtml+xml. Jeśli podajesz XHTML jako text/html, co musisz zrobić dla starszych wersji Internet Explorera, aby cokolwiek zrobić, zostanie on zinterpretowany jako HTML 4.01. Skrócona składnia może być używana tylko z dowolnym elementem, który pozwala na pominięcie znacznika zamykającego. Zobacz specyfikację HTML 4.01 .

XML 'krótka forma' jest interpretowana jako atrybut o nazwie /, który (ponieważ nie ma znaku równości) jest interpretowane jako posiadające wartość domyślną"/". Jest to całkowicie błędne w HTML 4.01 - nierejestrowane atrybuty są niedozwolone - ale przeglądarki zignorują to.

IE9 i późniejsze obsługują XHTML 5 serwowane z application/xhtml+xml.

 18
Author: Mike Dimmick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-05 17:10:41

To dlatego, że znacznik SCRIPT nie jest elementem VOID.

W dokumencie HTML - elementy VOID nie potrzebują w ogóle "znacznika zamykającego"!

W xhtml Wszystko jest ogólne, dlatego wszystkie wymagają zakończenia np. "znacznika zamknięcia"; w tym Br, prostego podziału linii, jako <br></br> lub jego skrótu <br />.

Jednak Element skryptu nigdy nie jest pustym ani parametrycznym elementem, ponieważ znacznik skryptu przed Wszystko inne jest instrukcją przeglądarki, a nie deklaracją opisu danych.

Zasadniczo, Instrukcja zakończenia semantycznego, np." znacznik zamknięcia " jest potrzebna tylko do przetwarzania instrukcji, których semantyka nie może być zakończona przez następny znacznik. Na przykład:

<H1> semantyka nie może być zakończona następującym <P>, ponieważ nie posiada wystarczająco dużo własnej semantyki, aby nadpisać i zakończyć poprzedni zestaw instrukcji H1. Chociaż będzie w stanie rozbij strumień na nową linię akapitu, nie jest on "wystarczająco mocny", aby nadpisać obecny rozmiar czcionki i styl linii-wysokość zalewając strumień, tzn. wyciekając z H1(ponieważ P go nie ma).

Oto jak i dlaczego została wymyślona sygnalizacja "/" (terminacja).

Ogólny no-description znacznik zakończenia, taki jak < />, wystarczyłby dla każdego pojedynczego upadku z napotkanej kaskady, np.: <H1>Title< /> ale nie zawsze jest to przypadek, ponieważ chcemy również być zdolni do "zagnieżdżania", wielokrotnego pośredniego tagowania strumienia: dzielenia na torrenty przed owijaniem / spadaniem na inną kaskadę. W konsekwencji Terminator ogólny, taki jak < />, nie byłby w stanie określić celu właściwości do zakończenia. Na przykład: <b>pogrubienie <i>pogrubienie-kursywa < /> kursywa </>normalnie. Bez wątpienia nie zrealizowałby naszych intencji i najprawdopodobniej zinterpretowałby je jako bold bold-itallic bold normal.

Tak powstaje pojęcie owijarki ie., urodził się. (Pojęcia te są tak podobne, że niemożliwe jest rozróżnienie i czasami ten sam element może mieć oba. <H1> jest jednocześnie opakowaniem i pojemnikiem. Natomiast <B> tylko wrapper semantyczny). Potrzebny nam zwykły, bez semantyki Pojemnik. I oczywiście pojawił się wynalazek elementu DIV.

Element DIV jest w rzeczywistości 2Br-kontener. Oczywiście pojawienie się CSS sprawiło, że cała sytuacja stała się dziwniejsza niż w innym przypadku i wywołało wielkie zamieszanie z wieloma wielkimi konsekwencjami - pośrednio!

Ponieważ za pomocą CSS można łatwo nadpisać natywne zachowanie pre & after BR nowo wynalezionego DIV, jest on często określany jako"nie rób niczego". Co jest oczywiście błędne! Div są elementami blokowymi i natywnie przerywają linię strumienia zarówno przed, jak i po sygnalizacji końcowej. Wkrótce Strona zaczęła cierpieć z powodu page DIV-itis. Większość z nich nadal jest.

Pojawienie się CSS z jego zdolnością do pełnego nadpisania i całkowicie redefiniowania natywnego zachowania dowolnego znacznika HTML, w jakiś sposób udało się zmylić i zamazać całe znaczenie istnienia HTML...

Nagle wszystkie znaczniki HTML pojawiły się jakby przestarzałe, zostały zniszczone, pozbawione pierwotnego znaczenia, tożsamości i celu. W jakiś sposób można odnieść wrażenie, że nie są już potrzebne. Powiedzenie: pojedynczy znacznik kontenera - owijarki wystarczyłby do prezentacji wszystkich danych. Wystarczy dodać wymagane atrybuty. Zamiast tego wymyślaj nazwy znaczników, a CSS zajmie się resztą.

Tak narodził się xhtml i oczywiście wielki tępy, tak drogo opłacany przez nowych przybyszów i zniekształconą wizję tego, co jest czym, i jaki jest cholerny cel tego wszystkiego. W3C poszedł z World Wide Web do co poszło nie tak, towarzysze?!!

Celem HTML jest aby strumień znaczących danych do ludzkiego odbiorcy.

Dostarczanie informacji.

Część formalna ma jedynie pomóc w zapewnieniu przejrzystości przekazywania informacji. xhtml nie bierze pod uwagę informacji. - Dla niego, informacja jest absolutnie nieistotna.

Najważniejszą rzeczą w tej sprawie jest wiedzieć i zrozumieć, że xhtml to nie tylko wersja jakiegoś rozszerzonego HTML, xhtml to zupełnie inna bestia; i dlatego mądrze jest trzymać je osobno.

 5
Author: Bekim Bacaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-09 01:46:30

Różnica między 'true XHTML', 'faux XHTML' i HTML, a także znaczenie typu MIME wysyłanego przez serwer została już dobrze opisana tutaj . Jeśli chcesz wypróbować go teraz, oto prosty, edytowalny fragment z podglądem na żywo, w tym samo-zamknięty znacznik skryptu dla zdolnych przeglądarek:

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>

Powinieneś zobaczyć Hello, true XHTML. Nice to meet you! poniżej textarea.

Dla przeglądarek można skopiować zawartość textarea i zapisać ją jako plik z .xhtml (lub .xht) extension (Dzięki Alek za podpowiedź ).

 3
Author: myf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-27 10:48:10

Po prostu Nowoczesna odpowiedź polega na tym, że znacznik jest oznaczony jako obowiązkowy w ten sposób

Pominięcie znacznika brak, zarówno znacznik początkowy, jak i końcowy są obowiązkowe.

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

 2
Author: Mark Schultheiss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-10 14:38:53