Búsqueda de sitios web

javascript - ¿Por qué no funcionan los elementos script autocerrados?


¿Cuál es la razón por la que los navegadores no reconocen correctamente:

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

Solo esto es reconocido:

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

¿Esto rompe el concepto de soporte de XHTML?

Nota: Esta afirmación es correcta al menos para todos los IE (6-8 beta 2).

Respuesta #1

El anexo no normativo ‘Directrices de compatibilidad con HTML’ de la especificación XHTML 1 dice:

C.3. Minimización de elementos y contenido de elementos vacíos

Dada una instancia vacía de un elemento cuyo modelo de contenido no es EMPTY (por ejemplo, un título o párrafo vacío), no use la forma minimizada (por ejemplo, use <p> </p> y no <p />).

El DTD de XHTML especifica los elementos de script como:

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

Respuesta #2

Para añadir a lo que han dicho Brad y su compañera de equipo, la sintaxis XML autocerrable <script /> en realidad es XML correcto, pero para que funcione en la práctica, tu servidor web también necesita enviar tus documentos como XML correctamente formado con un tipo MIME de XML como application/xhtml+xml en el encabezado HTTP Content-Type (y no como text/html).

Sin embargo, enviar un tipo de contenido XML hará que tus páginas no sean analizadas por IE7, que solo admite text/html.

De w3:

En resumen, 'application/xhtml+xml' DEBERÍA usarse para documentos de la familia XHTML, y el uso de 'text/html' DEBERÍA limitarse a documentos XHTML 1.0 compatibles con HTML. 'application/xml' y 'text/xml' TAMBIÉN PUEDEN usarse, pero siempre que sea apropiado, SE DEBERÍA usar 'application/xhtml+xml' en lugar de esos tipos de medios XML genéricos.

Me rompí la cabeza con esto hace unos meses, y la única solución viable (compatible con FF3+ e IE7) era usar la antigua sintaxis <script></script> con text/html (sintaxis HTML + tipo MIME HTML).

Si su servidor envía el tipo text/html en sus encabezados HTTP, incluso con documentos XHTML correctamente formados, FF3+ usará su modo de renderizado HTML, lo que significa que <script /> no funcionará (esto es un cambio, Firefox anteriormente era menos estricto).

Esto sucederá independientemente de cualquier manipulación de los elementos meta http-equiv, el prólogo XML o el doctype dentro de su documento -- Firefox bifurca una vez que recibe el encabezado text/html, eso determina si el analizador HTML o XML examina el documento, y el analizador HTML no entiende <script />.

Respuesta #3

Otros han respondido "cómo" y citado la especificación. Aquí está la verdadera historia de "por qué no <script/>", después de muchas horas investigando informes de errores y listas de correo.


HTML 4

HTML 4 se basa en SGML.

SGML tiene algunas etiquetas cortas, como <BR//, <B>texto</>, <B/text/, o <OL<LI>elemento</LI</OL>. XML toma la primera forma, redefine el cierre como ">" (SGML es flexible), de modo que se convierte en <BR/>.

Sin embargo, HTML no redefinió esto, por lo que <SCRIPT/> debería significar <SCRIPT>>.
(Sí, el '>' debería ser parte del contenido, y la etiqueta todavía no está cerrada.)

Obviamente, esto es incompatible con XHTML y romperá muchos sitios (para cuando los navegadores eran lo suficientemente maduros como para preocuparse por esto), por lo que nadie implementó los shorttags y la especificación los desaconseja.

Efectivamente, todas las etiquetas autocontenidas 'funcionantes' son etiquetas con etiqueta de cierre prohibida en analizadores técnicamente no conformes y, de hecho, son inválidas. Fue el W3C quien ideó este truco para ayudar en la transición a XHTML haciéndolo compatible con HTML.

Y la etiqueta de cierre de <script> no está prohibida.

La etiqueta "auto-cerrada" es un truco en HTML 4 y no tiene sentido.


HTML 5

HTML5 tiene cinco tipos de etiquetas y solo las etiquetas 'void' y 'foreign' pueden ser auto-cerradas.

Porque <script> no es vacío (puede tener contenido) y no es extranjero (como MathML o SVG), <script> no puede cerrarse a sí mismo, sin importar cómo lo uses.

¿Pero por qué? ¿No pueden considerarlo como algo extranjero, hacer una excepción o algo así?

HTML 5 apunta a ser compatible hacia atrás con las implementaciones de HTML 4 y XHTML 1. No se basa en SGML o XML; su sintaxis se preocupa principalmente por documentar y unificar las implementaciones. (Es por esto que <br/> <hr/> etc. son válidos en HTML 5 a pesar de ser inválidos en HTML4.)

El <script> que se cierra automáticamente es una de las etiquetas en las que las implementaciones solían diferir. Solía funcionar en Chrome, Safari y Opera; hasta donde yo sé, nunca funcionó en Internet Explorer ni en Firefox.

Esto se discutió cuando se estaba redactando HTML 5 y fue rechazado porque rompe la compatibilidad con los navegadores. Las páginas web que cierran automáticamente la etiqueta de script pueden no renderizarse correctamente (si es que lo hacen) en navegadores antiguos. Hubo otras propuestas, pero tampoco pueden resolver el problema de compatibilidad.

Después de que se publicó el borrador, WebKit actualizó el analizador para estar en conformidad.

El <script> autocerrable no ocurre en HTML 5 debido a la compatibilidad hacia atrás con HTML 4 y XHTML 1.


XHTML 1/XHTML 5

Cuando realmente se sirve como XHTML, <script/> está realmente cerrado, como otras respuestas han indicado.

Excepto que la especificación dice que debería haber funcionado cuando se sirve como HTML:

Los documentos XHTML ... pueden etiquetarse con el Tipo de Medio de Internet "text/html" [RFC2854], ya que son compatibles con la mayoría de los navegadores HTML.

Entonces, ¿qué pasó?

La gente pidió a Mozilla que permitiera a Firefox analizar documentos conformes como XHTML sin importar el encabezado de contenido especificado (conocido como detección de contenido). Esto habría permitido scripts autocontenidos, y la detección de contenido era necesaria de todos modos porque los anfitriones web no eran lo suficientemente maduros para servir el encabezado correcto; IE era bueno en ello.

Si la primera guerra de los navegadores no hubiera terminado con IE 6, XHTML también podría haber estado en la lista. Pero sí terminó. Y IE 6 tiene un problema con XHTML. De hecho, IE no soportaba el tipo MIME correcto en absoluto, lo que obligaba a todos a usar text/html para XHTML porque IE tenía una cuota de mercado importante durante toda una década.

Y también el análisis de contenido puede ser realmente malo y la gente dice que debería ser detenido.

Finalmente, resulta que el W3C no quería que XHTML fuera detectable: el documento es ambos, HTML y XHTML, y las reglas de Content-Type. Se puede decir que se mantenían firmes en "simplemente sigue nuestra especificación" e ignoraban lo que era práctico. Un error que continuó en versiones posteriores de XHTML.

De todos modos, esta decisión resolvió el asunto para Firefox. Pasaron 7 años antes de que naciera Chrome; no había otro navegador significativo. Así que se decidió.

Especificar solo el doctype no activa el análisis XML debido a las siguientes especificaciones.

Respuesta #4

En caso de que a alguien le interese, la razón última es que HTML era originalmente un dialecto de SGML, que es el extraño hermano mayor de XML. En el mundo de SGML, los elementos pueden especificarse en el DTD como autocontenidos (por ejemplo, BR, HR, INPUT), implícitamente cerrables (por ejemplo, P, LI, TD) o explícitamente cerrables (por ejemplo, TABLE, DIV, SCRIPT). XML, por supuesto, no tiene el concepto de esto.

Los analizadores de etiquetas desordenadas utilizados por los navegadores modernos evolucionaron a partir de este legado, aunque su modelo de análisis ya no es SGML puro. Y, por supuesto, tu XHTML cuidadosamente elaborado se trata como SGML mal escrito inspirado en etiquetas desordenadas a menos que lo envíes con un tipo MIME de XML. Esto también es por lo que...

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

...se interpreta por el navegador como:

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

...que es la receta para un encantador y oscuro error que puede hacer que te dé un ataque mientras intentas programar contra el DOM.

Respuesta #5

Internet Explorer 8 y versiones anteriores no soportan el análisis de XHTML. Incluso si utilizas una declaración XML y/o un tipo de documento XHTML, las versiones antiguas de IE todavía analizan el documento como HTML simple. Y en HTML simple, la sintaxis de autocierre no está soportada. La barra inclinada final simplemente se ignora, tienes que usar una etiqueta de cierre explícita.

Incluso los navegadores con soporte para el análisis de XHTML, como IE 9 y posteriores, seguirán analizando el documento como HTML a menos que sirvas el documento con un tipo de contenido XML. ¡Pero en ese caso, las versiones antiguas de IE no mostrarán el documento en absoluto!

Respuesta #6

Las personas anteriores ya han explicado bastante el problema, pero una cosa que podría aclarar las cosas es que, aunque la gente use <br/> y cosas similares todo el tiempo en documentos HTML, cualquier / en esa posición básicamente se ignora, y solo se usa cuando se intenta hacer algo que sea analizables tanto como XML y HTML. Prueba <p/>foo</p>, por ejemplo, y obtendrás un párrafo normal.

Respuesta #7

La etiqueta de script autocerrable no funcionará, porque la etiqueta de script puede contener código en línea, y HTML no es lo suficientemente inteligente como para activar o desactivar esa función según la presencia de un atributo.

Por otro lado, HTML sí tiene una excelente etiqueta para incluir referencias a recursos externos: la etiqueta <link>, y puede ser autocontenida. Ya se usa para incluir hojas de estilo, feeds RSS y Atom, URIs canónicas y todo tipo de otros elementos interesantes. ¿Por qué no JavaScript?

Si quieres que la etiqueta script sea autocontenida no puedes hacer eso como dije, pero hay una alternativa, aunque no sea muy inteligente. Puedes usar la etiqueta link autocerrada y enlazar tu JavaScript dándole un tipo de text/javascript y rel como script, algo así:

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

Respuesta #8

A diferencia de XML y XHTML, HTML no tiene conocimiento de la sintaxis de autocierre. Los navegadores que interpretan XHTML como HTML no saben que el carácter / indica que la etiqueta debe cerrarse automáticamente; en su lugar, lo interpretan como un atributo vacío y el analizador aún piensa que la etiqueta está 'abierta'.

Así como <script defer> se trata como <script defer="defer">, <script /> se trata como <script /="/">.

Respuesta #9

Internet Explorer 8 y versiones anteriores no soportan el tipo MIME correcto para XHTML, application/xhtml+xml. Si estás sirviendo XHTML como text/html, lo cual tienes que hacer para que estas versiones antiguas de Internet Explorer puedan hacer algo, será interpretado como HTML 4.01. Solo puedes usar la sintaxis corta con cualquier elemento que permita omitir la etiqueta de cierre. Consulta la Especificación de HTML 4.01.

La 'forma corta' de XML se interpreta como un atributo llamado /, que (debido a que no hay un signo igual) se interpreta como si tuviera un valor implícito de "/". Esto es estrictamente incorrecto en HTML 4.01: no se permiten atributos no declarados, pero los navegadores lo ignorarán.

IE9 y versiones posteriores son compatibles con XHTML 5 servido con application/xhtml+xml.

Artículos relacionados