it-swarm-eu.dev

Warum funktionieren selbstschließende Skriptelemente nicht?

Was ist der Grund, warum Browser Folgendes nicht richtig erkennen:

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

Nur dies wird erkannt:

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

Verstößt dies gegen das Konzept der XHTML-Unterstützung?

Hinweis: Diese Aussage ist zumindest für alle IE (6-8 Beta 2) korrekt.

1260
dimarzionist

Die XHTML 1-Spezifikation besagt:

С.3. Elementminimierung und leerer Elementinhalt

Verwenden Sie bei einer leeren Instanz eines Elements, dessen Inhaltsmodell nicht EMPTY ist (z. B. ein leerer Titel oder Absatz), nicht die minimierte Form (z. B. verwenden Sie <p> </p> und nicht <p />).

XHTML DTD spezifiziert Skriptelemente als:

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

Die selbstschließende XML-Syntax <script /> ist tatsächlich korrektes XML , funktioniert aber trotzdem In der Praxis muss Ihr Webserver Ihre Dokumente auch als ordnungsgemäß formatiertes XML mit einem XML-Mimetyp wie application/xhtml+xml im HTTP-Content-Type-Header senden (und nicht als text/html).

Wenn Sie jedoch einen XML-Mimetyp senden, werden Ihre Seiten nicht vom IE7 analysiert, der nur text/html verwendet.

Von w :

Zusammenfassend sollte "application/xhtml + xml" für Dokumente der XHTML-Familie verwendet werden, und die Verwendung von "text/html" sollte auf HTML-kompatible XHTML 1.0-Dokumente beschränkt sein. 'application/xml' und 'text/xml' KÖNNEN ebenfalls verwendet werden. Gegebenenfalls sollte jedoch 'application/xhtml + xml' anstelle dieser generischen XML-Medientypen verwendet werden.

Ich habe vor ein paar Monaten darüber nachgedacht, und die einzige praktikable (mit FF3 + und IE7 kompatible) Lösung war die Verwendung der alten <script></script> -Syntax mit text/html (HTML-Syntax + HTML-Mimetyp).

Wenn Ihr Server den Typ text/html in seinen HTTP-Headern sendet, verwendet FF3 + auch bei ordnungsgemäß formatierten XHTML-Dokumenten den HTML-Rendering-Modus. Dies bedeutet, dass <script /> nicht funktioniert (dies ist eine Änderung, die Firefox vorgenommen hat) vorher weniger streng).

Dies geschieht unabhängig davon, ob Sie mit http-equiv Metaelementen, dem XML-Prolog oder dem Doctype in Ihrem Dokument fummeln - Firefox verzweigt sich, sobald der Header text/html angezeigt wird, der bestimmt, ob der HTML- oder XML-Parser im Textbereich angezeigt wird Dokument, und der HTML-Parser versteht <script /> nicht.

231
joelhardi

Falls jemand neugierig ist, der letzte Grund ist, dass HTML ursprünglich ein Dialekt von SGML war, dem seltsamen älteren Bruder von XML. In SGML-Land können Elemente in der DTD entweder als selbstschließend (z. B. BR, HR, INPUT), implizit schließend (z. B. P, LI, TD) oder explizit schließend (z. B. TABLE, DIV, SCRIPT) angegeben werden. XML hat natürlich kein Konzept dafür.

Die Tag-Suppe-Parser, die von modernen Browsern verwendet werden, sind aus diesem Erbe hervorgegangen, obwohl ihr Parser-Modell kein reines SGML mehr ist. Und natürlich wird Ihr sorgfältig erstelltes XHTML als schlecht geschriebene SGML-inspirierte Tag-Suppe behandelt, es sei denn, Sie senden es mit einem XML-MIME-Typ. Das ist auch der Grund, warum ...

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

... wird vom Browser interpretiert als:

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

... das ist das Rezept für einen schönen obskuren Fehler, der Sie in Schwierigkeiten bringen kann, wenn Sie versuchen, gegen das DOM zu programmieren.

154
greim

Andere haben mit "wie" geantwortet und Angaben gemacht. Hier ist die wahre Geschichte von "why no <script/>", nach vielen Stunden in Fehlerberichten und Mailinglisten zu stöbern.


HTML 4

HTML 4 basiert auf SGML .

SGML verfügt über einige Shorttags , z. B. <BR//, <B>text</>, <B/text/ oder <OL<LI>item</LI</OL>. XML nimmt die erste Form an und definiert die Endung als ">" neu (SGML ist flexibel), sodass sie zu <BR/> wird.

HTML wurde jedoch nicht neu definiert, daher <SCRIPT/> sollte bedeuten<SCRIPT>>.
(Ja, das '>' sollte Teil des Inhalts sein und das Tag ist immer noch nicht geschlossen.)

Offensichtlich ist dies inkompatibel mit XHTML und wird bricht viele Websites (zu der Zeit, als die Browser ausgereift genug waren, sich zu kümmerndarüber ), also niemand implementiert) Shorttags und die Spezifikation rät davon ab .

Tatsächlich sind alle "funktionierenden" Self-Ended-Tags Tags mit optionalem End-Tag für technisch nicht konforme Parser und tatsächlich ungültig. Es war W3C, das mit diesem Hack kam, um den Übergang zu XHTML zu erleichtern, indem es HTML-kompatibel gemacht wurde.

Das Endtag von <script> ist nicht optional .

"Self-Ending" -Tag ist ein Hack in HTML 4 und bedeutungslos.


HTML 5

HTML5 hat fünf Arten von Tags und nur 'void' und 'foreign' Tags sind dürfen sich selbst schließen .

Da <script> nicht ungültig ist (es may have content) und nicht fremd ist (wie MathML oder SVG), kann <script> nicht selbst geschlossen werden, unabhängig davon, wie Sie es verwenden.

Aber wieso? Können sie es nicht als fremd ansehen, Sonderfälle machen oder so?

HTML 5 soll abwärtskompatibel mit Implementierungen von HTML 4 und XHTML 1 sein. Es basiert nicht auf SGML oder XML. Die Syntax befasst sich hauptsächlich mit der Dokumentation und Vereinheitlichung der Implementierungen. (Aus diesem Grund sind <br/><hr/> usw. gültiges HTML 5 , obwohl sie ungültiges HTML4 sind.)

Selbstschließendes <script> ist eines der Tags, bei denen Implementierungen unterschiedlich waren. Es verwendet, um in Chrome, Safari zu arbeiten , nd Opera ; meines wissens hat es in internet explorer oder firefox nie funktioniert.

Dies wurde besprochen als HTML 5 entworfen und abgelehnt wurde, weil es brichtBrowserKompatibilität . Webseiten, deren Skript-Tag sich selbst schließt, werden in alten Browsern möglicherweise (wenn überhaupt) nicht richtig gerendert. Es gab andere Vorschläge , aber sie können auch das Kompatibilitätsproblem nicht lösen.

Nach der Veröffentlichung des Entwurfs hat WebKit den Parser so aktualisiert, dass er den Anforderungen entspricht.

Selbstschließendes <script> tritt in HTML 5 aufgrund der Abwärtskompatibilität zu HTML 4 und XHTML 1 nicht auf.


XHTML 1/XHTML 5

Wenn really als XHTML gedient hat, ist <script/> wirklich geschlossen, wie andere Antworten angegeben hat.

Abgesehen davon, dass die Spezifikation sagt es sollte funktioniert haben, wenn es als HTML geliefert wurde:

XHTML-Dokumente ... sind möglicherweise mit dem Internet-Medientyp "text/html" [RFC2854] gekennzeichnet, da sie mit den meisten HTML-Browsern kompatibel sind.

Also was ist passiert?

Personen Mozilla gefragt bis Firefox analysieren lassen konforme Dokumente als XHTML , unabhängig vom angegebenen Inhaltsheader (als Content Sniffing bekannt). Dies hätte selbstschließende Skripte und Content-Sniffing war erforderlich ermöglicht, da Webhoster nicht ausgereift genug waren, um den richtigen Header bereitzustellen. IE war gut darin .

Wenn der erste Browserkrieg nicht mit IE 6 endete, war möglicherweise auch XHTML auf der Liste. Aber es ging zu Ende. Und IE 6 hat ein Problem mit XHTML. Tatsächlich IE hat nicht unterstützt der richtige MIME-Typ überhaupt , wodurch everyone gezwungen wird, text/html für XHTML zu verwenden, weil IE hatte großen Marktanteil für ein ganzes Jahrzehnt.

Und auch das Schnüffeln von Inhalten kann seinwirklich schlecht und die Leute sagen es sollte gestoppt werden .

Schließlich stellt sich heraus, dass das W3C XHTML sollte nicht abhörbar sein : das Dokument ist sowohl , HTML und XHTML, als auch Content-Type-Regeln. Man kann sagen, sie standen fest auf "folgen Sie einfach unserer Spezifikation" und ignorieren, was praktisch war . Ein Fehler, der Fortsetzung in späteren XHTML-Versionen.

Wie auch immer, diese Entscheidung hat die Sache geklärt für Firefox. Es war 7 Jahre vor Chrome wurde geboren ; Es gab keinen anderen wichtigen Browser. So wurde entschieden.

Die Angabe des Doctype allein löst aufgrund der folgenden Angaben kein XML-Parsing aus.

141
Sheepy

Internet Explorer 8 und frühere Versionen unterstützen keine XHTML-Analyse. Auch wenn Sie eine XML-Deklaration und/oder einen XHTML-Doctype verwenden, wird das Dokument vom alten IE weiterhin als reines HTML analysiert. In einfachem HTML wird die selbstschließende Syntax nicht unterstützt. Der abschließende Schrägstrich wird einfach ignoriert, Sie müssen ein explizites schließendes Tag verwenden.

Sogar Browser, die XHTML-Parsing unterstützen, wie z. B. IE 9 und höher , analysieren das Dokument weiterhin als HTML, es sei denn, Sie liefern das Dokument mit einem XML-Inhaltstyp. In diesem Fall zeigt das alte IE das Dokument jedoch überhaupt nicht an!

44
JacquesB

Die oben genannten Personen haben das Problem bereits ziemlich genau erklärt, aber eine Sache, die die Dinge klarstellen könnte, ist, dass, obwohl die Leute <br/> und so oft in HTML-Dokumenten verwenden, jeder / in einer solchen Position ist Grundsätzlich ignoriert und nur verwendet, wenn versucht wird, etwas sowohl als XML als auch als HTML analysierbar zu machen. Versuchen Sie beispielsweise <p/>foo</p>, und Sie erhalten einen regulären Absatz.

27
Marijn

Das selbstschließende Skript-Tag funktioniert nicht, da das Skript-Tag Inline-Code enthalten kann und HTML nicht intelligent genug ist, um diese Funktion basierend auf dem Vorhandensein eines Attributs zu aktivieren oder zu deaktivieren.

Andererseits verfügt HTML über ein ausgezeichnetes Tag zum Einschließen von Verweisen auf externe Ressourcen: das Tag <link>, und es kann sich selbst schließen. Es wird bereits verwendet, um Stylesheets, RSS- und Atom-Feeds, kanonische URIs und alle möglichen anderen Extras einzuschließen. Warum nicht JavaScript?

Wenn Sie möchten, dass das Skript-Tag in sich geschlossen ist, können Sie das nicht tun, wie ich bereits sagte, aber es gibt eine Alternative, wenn auch keine clevere. Sie können das selbstschließende Link-Tag verwenden und auf Ihr JavaScript verlinken, indem Sie ihm eine Art Text/Javascript und rel als Skript geben, etwa wie folgt:

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

Im Gegensatz zu XML und XHTML kennt HTML die sich selbst schließende Syntax nicht. Browser, die XHTML als HTML interpretieren, wissen nicht, dass das Zeichen / angibt, dass das Tag sich selbst schließen soll. Stattdessen interpretieren sie es wie ein leeres Attribut und der Parser denkt immer noch, dass das Tag 'offen' ist.

Genau wie <script defer> als <script defer="defer"> behandelt wird, wird <script /> als <script /="/"> behandelt.

20
rpetrich

Internet Explorer 8 und älter unterstützen nicht den richtigen MIME-Typ für XHTML, application/xhtml+xml. Wenn Sie XHTML als text/html bereitstellen, was für diese älteren Versionen von Internet Explorer erforderlich ist, wird es als HTML 4.01 interpretiert. Sie können die kurze Syntax nur für Elemente verwenden, bei denen das schließende Tag weggelassen werden kann. Siehe HTML 4.01-Spezifikation .

Die XML-Kurzform wird als Attribut mit dem Namen/interpretiert, das (da es kein Gleichheitszeichen gibt) als impliziten Wert "/" interpretiert wird. Dies ist in HTML 4.01 strikt falsch - nicht deklarierte Attribute sind nicht zulässig - aber Browser ignorieren dies.

IE9 und höher nterstützt XHTML 5 wird mit application/xhtml+xml bereitgestellt.

18
Mike Dimmick

Das liegt daran, dass SCRIPT TAG kein LEERES ELEMENT ist.

In einem HTML-Dokument - VOID ELEMENTS nicht benötigen Sie überhaupt ein "schließendes Tag"!

In xhtml ist alles generisch, daher benötigen alle Terminierung z. ein "schließendes Etikett"; Einschließlich br, ein einfacher Zeilenumbruch, wie <br></br> oder dessen Kurzform <br />.

Ein Script-Element ist jedoch niemals ein ungültiges oder parametrisches Element, da Script-Tag vor allem anderen eine Browser-Anweisung und keine Datenbeschreibungsdeklaration ist.

Grundsätzlich wird ein semantischer Beendigungsbefehl, z. B. ein "schließender Tag", nur zum Verarbeiten von Befehlen benötigt, deren Semantik nicht durch einen nachfolgenden Tag beendet werden kann. Zum Beispiel:

<H1> Semantik kann nicht durch einen folgenden <P> beendet werden, da nicht genügend eigene Semantik vorhanden ist, um den vorherigen H1-Befehlssatz zu überschreiben und damit zu beenden. Obwohl es in der Lage ist, das stream in eine neue Absatzzeile zu unterteilen, ist es nicht "stark genug", um die aktuelle Schriftgröße und die aktuelle Zeilenhöhe außer Kraft zu setzen den Strom runter , dh aus H1 austreten (weil P es nicht hat).

Dies ist, wie und warum die "/" (Terminierung) Signalisierung erfunden wurde.

Ein generisches unbeschreibliches Termination Tag wie < /> hätte für jeden einzelnen Sturz der angetroffenen Kaskade ausgereicht, zB: <H1>Title< /> aber das ist nicht immer der Fall, weil wir auch in der Lage sein wollen, mehrere zwischengeschaltete Tags des Streams "zu verschachteln": In Torrents aufteilen, bevor er auf eine andere Kaskade gewickelt/fallen gelassen wird. Folglich kann ein generischer Terminator wie < /> das Ziel einer zu terminierenden Eigenschaft nicht bestimmen. Zum Beispiel: <b>fett<i> fett-kursiv < /> kursiv </>normal. Würde zweifellos unsere Absicht verfehlen und sie höchstwahrscheinlich als fett fett-kursiv fett normal interpretieren.

Auf diese Weise wurde der Begriff eines Wrappers, dh eines Containers, geboren. (Diese Begriffe sind so ähnlich, dass es unmöglich ist, beide zu erkennen, und manchmal kann dasselbe Element beides enthalten. <H1> ist gleichzeitig Wrapper und Container. Während <B> nur ein semantischer Wrapper ist). Wir brauchen einen einfachen Container ohne Semantik. Und natürlich kam die Erfindung eines DIV-Elements vorbei.

Das DIV-Element ist eigentlich ein 2BR-Container. Natürlich machte das Kommen von CSS die ganze Situation seltsamer als es sonst gewesen wäre und verursachte eine große Verwirrung mit vielen großen Konsequenzen - indirekt!

Da Sie mit CSS das native Pre- und After-BR-Verhalten eines neu erfundenen DIV leicht überschreiben können, wird es häufig als "Do-nothing-Container" bezeichnet. Welches ist natürlich falsch! DIVs sind Blockelemente und unterbrechen nativ die Leitung des Streams sowohl vor als auch nach der Endsignalisierung. Bald begann das WEB unter der Seite DIV-itis zu leiden. Die meisten von ihnen sind es noch.

Das Kommen von CSS mit seiner Fähigkeit, das native Verhalten eines HTML-Tags vollständig zu überschreiben und neu zu definieren, hat es irgendwie geschafft, die gesamte Bedeutung der HTML-Existenz zu verwirren und zu verwischen ...

Plötzlich erschienen alle HTML-Tags als obsolet, sie wurden unkenntlich gemacht und ihrer ursprünglichen Bedeutung, Identität und ihres Zwecks beraubt. Irgendwie würde man den Eindruck gewinnen, dass sie nicht mehr gebraucht werden. Sprichwort: Ein einziges Container-Wrapper-Tag würde für die gesamte Datenpräsentation ausreichen. Fügen Sie einfach die erforderlichen Attribute hinzu. Warum nicht stattdessen aussagekräftige Tags verwenden? Erfinden Sie Tag-Namen, während Sie fortfahren, und lassen Sie das CSS den Rest erledigen.

So wurde xhtml geboren und natürlich die große Stumpfe, die von Neuankömmlingen so teuer bezahlt wurde und eine verzerrte Vorstellung davon, was was ist und was der verdammte Zweck von allem ist. W3C ging vom World Wide Web zu What Went Wrong, Genossen? !!

Der Zweck von HTML ist zum Streamen sinnvolle Daten an den menschlichen Empfänger.

Informationen zu liefern.

Der formale Teil dient lediglich der Klarheit der Informationsübermittlung. xhtml berücksichtigt die Informationen nicht im geringsten. - Für sie sind die Informationen absolut irrelevant.

Das Wichtigste in dieser Angelegenheit ist, zu wissen und verstehen zu können, dass xhtml ist nicht nur eine Version von erweitertem HTML, xhtml ist ein ganz anderes Biest; Gründe; und deshalb es ist ratsam, sie getrennt zu halten.

5
Bekim Bacaj

Der Unterschied zwischen 'true XHTML', 'faux XHTML' und HTML sowie die Bedeutung des vom Server gesendeten MIME-Typs waren hier bereits gut beschrieben . Wenn Sie es gleich ausprobieren möchten, finden Sie hier ein einfaches, bearbeitbares Snippet mit Live-Vorschau und selbstgeschlossenem Skript-Tag für fähige Browser:

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>

Sie sollten Hello, true XHTML. Nice to meet you! unter dem Textbereich sehen.

Bei unfähigen Browsern können Sie den Inhalt des Textbereichs kopieren und als Datei mit der Erweiterung .xhtml (oder .xht) speichern ( danke Alek für diesen Hinweis ).

2
myf