¿Realmente necesito codificar '&' como '& amp;'?

207

Estoy usando un &símbolo ' ' con HTML5 y UTF-8 en mi sitio <title>. Google muestra el ampersand bien en sus SERPs, al igual que todos los navegadores en sus títulos.

http://validator.w3.org me está dando esto:

& no inició una referencia de caracteres. (Y probablemente debería haberse escapado como &amp;.)

¿Realmente necesito hacer &amp;?

No estoy preocupado por la validación de mis páginas en aras de la validación, pero tengo curiosidad por escuchar las opiniones de las personas sobre esto y si es importante y por qué.

Haroldo
fuente
63
Las especificaciones no lo dicen. El póster se refiere a HTML5 que no requiere escapar del ampersand en todos los escenarios.
Matthew Wilson
2
Esto debería ser Community Wiki, ya que estás buscando opiniones, y no ser exigente con la validación implica que no hay una base objetiva sobre la cual responder.
Richard JP Le Guen
66
@ Richard: ¿en serio? Si bien no estoy de acuerdo con que "la validación no importa", veo esto como una pregunta muy objetiva: "¿esto rompe algo más que la especificación?"
Joachim Sauer
2
@YiJiang Los navegadores web actuales hacen todo lo posible para comprender al usuario . Y también lo hace Google . Es parte de la especificación. Los futuros navegadores web pueden ser menos indulgentes. Por lo tanto, siempre es una buena idea verificar cómo lo hace Wikipedia y copiarlos.
unixman83
2
La especificación HTML dice que acepte la entrada de basura. ¿Eso significa que su sitio está "permitido" ser basura ahora? ¡Cierra las etiquetas que deben cerrarse y escapa de las cosas! Vamos gente.
doug65536

Respuestas:

143

Si. Tal como decía el error, en HTML, los atributos son #PCDATA, lo que significa que se analizan. Esto significa que puede usar entidades de caracteres en los atributos. El uso &por sí solo es incorrecto y si no fuera por navegadores indulgentes y el hecho de que esto es HTML no XHTML, rompería el análisis. Simplemente escapa como &amp;y todo estaría bien.

HTML5 le permite dejarlo sin escape, pero solo cuando los datos que siguen no parecen una referencia de caracteres válida. Sin embargo, es mejor escapar de todas las instancias de este símbolo que preocuparse por cuáles deberían ser y cuáles no.

Tenga este punto en mente; si no está escapando & a & amp ;, es lo suficientemente malo para los datos que crea (donde el código podría ser inválido), también podría no estar escapando delimitadores de etiquetas, lo cual es un gran problema para los datos enviados por el usuario, que bien podría conducir a la inyección de HTML y script, robo de cookies y otras vulnerabilidades.

Por favor, solo escapa de tu código. Le ahorrará muchos problemas en el futuro.

Delan Azabani
fuente
9
Ningún navegador "malinterpretará" a & por sí solo. Cada navegador existente lo muestra como "&". Teniendo en cuenta que pidió explícitamente una razón práctica para hacerlo, y que declaró que no le importa la validación ..
Thomas Bonini
47
Si. Pero, moralmente, ¿deberíamos confiar en la indulgencia y el "buen" manejo de errores de los navegadores? ¿O deberíamos simplemente escribir el código correcto?
Delan Azabani
8
@Delan: mientras trato de validar cada página que escribo, entiendo por leer su pregunta que no le importa "moralmente". Solo le importa si funciona o no. Son dos filosofías diferentes y ambas tienen sus pros y sus contras, y no hay una "correcta". Por ejemplo, este sitio web no se valida y, sin embargo, es un gran sitio web.
Thomas Bonini
3
@Andreas, pero los navegadores tienen suficientes errores en la forma en que interpretan el código correcto, dependiendo de que obtengan los resultados correctos cuando les envíes un marcado sin sentido, es algo cambiante. Puede funcionar hoy con ese ejemplo, y luego fallar con el siguiente ejemplo (digamos si el siguiente ejemplo tiene un punto y coma en algún lugar después del &)
Jon Hanna
11
Todo el mundo parece estar hablando de HTML5, pero la pregunta original dice que HTML5 está en uso. HTML5 explícitamente permite un sin escape y en esta situación, a menos que lo que sigue y normalmente se expandiría a una entidad (por ejemplo, & copy = 2 es problemático pero & x = 2 está bien).
Matthew Wilson
55

Dejando a un lado la validación, el hecho es que codificar ciertos caracteres es importante para un documento HTML para que pueda representarse de manera adecuada y segura como una página web.

Codificar &como &amp;en todas las circunstancias, para mí, es una regla más fácil de cumplir, lo que reduce la probabilidad de errores y fallas.

Compare lo siguiente: ¿cuál es más fácil? ¿ Cuál es más fácil de fastidiar ?

Metodología 1

  1. Escriba algún contenido que incluya caracteres y símbolos.
  2. Codifícalos a todos.

Metodología 2

(con un grano de sal, por favor;))

  1. Escriba algún contenido que incluya un signo de y comercial.
  2. Caso por caso, mire cada ampersand. Determine si:
    • Está aislado y, como tal, sin ambigüedad, un signo de unión. p.ej. volt & amp
       > En ese caso, no te molestes en codificarlo.
    • No está aislado, pero usted siente que no es ambiguo, ya que la entidad resultante no existe y nunca existirá, ya que la lista de entidades nunca podría evolucionar. ej. amp&volt
       > En ese caso, no te molestes en codificarlo.
    • No está aislado y es ambiguo. p.ej. volt&amp
       > Codifícalo.

??

Richard JP Le Guen
fuente
3
El segundo caso de amp&volt es ambiguo: ¿es &voltahora una referencia de entidad o no?
Gumbo
66
@Gumbo El ampersand in noamp&volt es un ampersand ambiguo (según la definición en la especificación HTML). Ver mathiasbynens.be/notes/ambiguous-ampersands y mothereff.in/ampersands#amp%26volt .
Mathias Bynens el
@MathiasBynens En este momento (2019), la definición de un ampersand ambiguo parece haber cambiado un poco de la definición que citó en 2011 en mathiasbynens.be/notes/ambiguous-ampersands .
Jacob C. dice Restablecer a Mónica el
21

Las reglas HTML5 son diferentes de HTML4. No es necesario en HTML5, a menos que parezca que comienza un nombre de parámetro. "& copy = 2" sigue siendo un problema, por ejemplo, ya que & copy; Es el símbolo de copyright.

Sin embargo, me parece que es más difícil decidir codificar o no codificar dependiendo del siguiente texto. Entonces, el camino más fácil es probablemente codificar todo el tiempo.

Matthew Wilson
fuente
2
Es como citar valores de atributos: no tiene que hacerlo, pero no puede equivocarse si lo hace todo el tiempo.
Paul D. Waite el
3
&copy=2No es un problema tan grande como puede pensar. En los valores de atributo (por ejemplo, el hrefatributo), &copyno se considerará como una referencia de caracteres para ©. Fuera de un valor de atributo, lo haría.
Mathias Bynens
Dado que un ampersand normalmente va precedido y seguido de un espacio en texto en inglés, no es difícil recordar o pensar en la regla que sigo: si el ampersand no toca otro personaje visible, que es casi siempre, entonces no necesita codificación De lo contrario, solo codifique por simplicidad.
Carl Smith
¿Podría agregar una referencia a las reglas HTML5?
Ferrybig
17

Creo que esto se ha convertido en una cuestión de "por qué seguir las especificaciones cuando los navegadores no me importan". Aquí está mi respuesta generalizada:

Las normas no son una cosa "presente". Son una cosa "futura". Si nosotros, como desarrolladores, seguimos los estándares web, entonces es más probable que los proveedores de navegadores implementen esos estándares correctamente, y nos acerquemos a una web completamente interoperable, donde los hacks CSS, la detección de características y la detección del navegador no son necesarios. Donde no tenemos que descubrir por qué nuestros diseños se rompen en un navegador en particular, o cómo solucionarlo.

Específicamente, si HTML5 no requiere el uso de & amp; en su situación específica, y está utilizando un doctype HTML5 (y también espera que sus usuarios usen navegadores compatibles con HTML5), entonces no hay razón para hacerlo.

Ryan Kinal
fuente
1
Dicho esto, en términos generales, debe recordar que la mayoría de las formas "estándar" todavía están en modo borrador y pueden cambiar en el futuro.
refaelio
6

Bueno, si proviene de la entrada del usuario, absolutamente sí, por razones obvias. Piense si este mismo sitio web no lo hiciera: el título de esta pregunta se mostrará como ¿realmente necesito codificar '&' como '&'?

Si es algo así echo '<title>Dolce & Gabbana</title>';, estrictamente hablando, no tiene que hacerlo. Sería mejor, pero si no lo hace, ningún usuario notará la diferencia.

Thomas Bonini
fuente
5

¿Podrías mostrarnos cuál es tu titlerealidad? Cuando presente

<!DOCTYPE html>
<html>
<title>Dolce & Gabbana</title>
<body>
<p>am i allowed loose & mpersands?</p>
</body>
</html>

a http://validator.w3.org/ - pidiéndole explícitamente que use el modo experimental HTML 5 - no tiene quejas sobre el &s ...

AakashM
fuente
1
Sí, HTML5 tiene un analizador diferente que los analizadores HTML y XHTML anteriores, y permite símbolos sin escape en ciertas situaciones.
kevinji
En lo que respecta a estos ejemplos, esto no es nada nuevo en HTML5. Ambos <title>Dolce & Gabbana</title>y <p>Dolce & Gabbana</p>son válidos HTML 2.0.
Mathias Bynens el
4

En HTML, &marca el comienzo de una referencia, ya sea de una referencia de caracteres o de una referencia de entidad . A partir de ese momento, el analizador espera que #denote una referencia de carácter o un nombre de entidad que denote una referencia de entidad, ambos seguidos de a ;. Ese es el comportamiento normal.

Pero si el nombre de referencia o simplemente la apertura de referencia &es seguido por un espacio en blanco u otros delimitadores, ", ', <, >, &, el final ;e incluso una referencia para representar una llanura &se puede omitir:

<p title="&amp;">foo &amp; bar</p>
<p title="&amp">foo &amp bar</p>
<p title="&">foo & bar</p>

Solo en estos casos ;se puede omitir el final o incluso la referencia en sí (al menos en HTML 4). Creo que HTML 5 requiere el final ;.

Pero la especificación recomienda usar siempre una referencia como la referencia de caracteres &#38;o la referencia de entidad &amp;para evitar confusiones:

Los autores deben usar " &amp;" (ASCII decimal 38) en lugar de " &" para evitar confusión con el comienzo de una referencia de caracteres (delimitador abierto de referencia de entidad). Los autores también deben usar " &amp;" en los valores de los atributos ya que las referencias de caracteres están permitidas dentro de los valores de los atributos CDATA.

Gumbo
fuente
1
Esa es la especificación HTML 4 a la que se vincula; de mi lectura de la especificación (borrador) HTML 5, solo se anulan los símbolos ambiguos . Un signo "&" seguido de un espacio, por ejemplo, no es ambiguo, por lo que (de nuevo según mi lectura) debería permitirse: vea mi respuesta para el marcado que acepta el validador HTML 5.
AakashM
1
@AakashM: No estoy seguro, sonaba así.
Gumbo
3

Si el usuario se lo pasa, o terminará en una URL, debe escapar.

Si aparece en texto estático en una página? Todos los navegadores obtendrán este correcto de cualquier manera, no se preocupe mucho, ya que funcionará.

Dean J
fuente
3

Actualización (marzo de 2020): el validador del W3C ya no se queja de escapar de las URL.

Estaba comprobando por qué la URL de la imagen necesita escapar, por lo tanto, lo intenté en https://validator.w3.org . La explicación es bastante buena. Destaca que incluso las URL deben escaparse. [PD: supongo que se escapará cuando se consuma, ya que la URL lo necesita &. ¿Alguien puede aclarar?]

<img alt="" src="foo?bar=qut&qux=fop" />

Se encontró una referencia de entidad en el documento, pero no hay ninguna referencia con ese nombre definido. A menudo, esto se debe a escribir mal el nombre de referencia, a los símbolos sin codificar, o al dejar el punto y coma final (;). La causa más común de este error son los símbolos sin codificar en las URL, tal como lo describe el WDG en "Ampersands in URLs". Las referencias de entidad comienzan con un ampersand (&) y terminan con un punto y coma (;). Si desea utilizar un ampersand literal en su documento, debe codificarlo como "&" (¡incluso dentro de las URL!). Tenga cuidado de finalizar las referencias de entidad con un punto y coma o su referencia de entidad puede interpretarse en relación con el siguiente texto. También tenga en cuenta que las referencias de entidades con nombre distinguen entre mayúsculas y minúsculas; & Aelig; y æ son personajes diferentes.

Nishant
fuente
1
Lea la respuesta más votada. Los atributos son #PCDATA y, por lo tanto, se analizan. Las entidades se manejan allí. En su ejemplo, &comienza una referencia de entidad. Después de leer &qux, el analizador no encuentra punto y coma final ( ;), pero se encuentra con un signo igual ( =), que no puede ser parte del nombre de la entidad. Esto debería ser un error de análisis, si el analizador intentó ser realmente estricto (de acuerdo con HTML 4). En HTML 5, el análisis de entidades es en general más relajado.
Palec
1
Sospecho que, en general, es mejor usarlo ;como separador en las cadenas de consulta (cuando controlas el enlace) por ese motivo.
Demi el
2

Sí, debe intentar proporcionar un código válido si es posible.

La mayoría de los navegadores corregirán silenciosamente este error, pero existe un problema al confiar en el manejo de errores en los navegadores. No hay un estándar sobre cómo manejar el código incorrecto, por lo que depende de cada proveedor de navegador tratar de averiguar qué hacer con cada error, y los resultados pueden variar.

Algunos ejemplos en los que es probable que los navegadores reaccionen de manera diferente es si coloca elementos dentro de una tabla pero fuera de las celdas de la tabla, o si anida enlaces uno dentro del otro.

Para su ejemplo específico, no es probable que cause ningún problema, pero la corrección de errores en el navegador podría, por ejemplo, hacer que el navegador cambie del modo compatible con los estándares al modo peculiar, lo que podría hacer que su diseño se descomponga por completo.

Por lo tanto, debe corregir errores como este en el código, si no fuera por cualquier otra cosa, para mantener corta la lista de errores en el validador, de modo que pueda detectar problemas más serios.

Guffa
fuente
2

Hace un par de años, recibimos un informe de que una de nuestras aplicaciones web no se mostraba correctamente en Firefox. Resultó que la página contenía una etiqueta que parecía

<div style="..." ... style="...">

Cuando se enfrenta a un atributo de estilo repetido, IE combina ambos estilos, mientras que Firefox solo usa uno de ellos, de ahí el comportamiento diferente. Cambié la etiqueta a

<div style="...; ..." ...>

y efectivamente, ¡solucionó el problema! La moraleja de la historia es que los navegadores tienen un manejo más consistente de HTML válido que de HTML no válido. Entonces, ¡arregla tu maldito marcado ya! (O use HTML Tidy para arreglarlo).

dan04
fuente
1

si &se usa en html, entonces deberías escapar

Si &se usa en cadenas de JavaScript, por ejemplo, an alert('This & that');o document.href, no necesita usarlo.

Si está usando document.write, entonces debe usarlo, por ejemplo document.write(<p>this &amp; that</p>)

Alex
fuente
document.writedebería ser evitado. Vea el cuadro de advertencia en w3.org/html/wg/drafts/html/master/dom.html#document.write%28%29
Oriol
Buen punto sobre document.write(). Pero el punto general que Alex está haciendo sobre escribir en el documento desde los guiones, en mi opinión. +1
Patrick M
1

Depende de la probabilidad de que un punto y coma termine cerca de usted &, lo que hace que muestre algo bastante diferente.

Por ejemplo, cuando se trata de la entrada de los usuarios (por ejemplo, si incluye el tema proporcionado por el usuario de una publicación en el foro en sus etiquetas de título), nunca se sabe dónde podrían estar poniendo puntos y comas al azar, y podría mostrar al azar entidades extrañas. Así que siempre escapa en esa situación.

Para su propio html estático, seguro, puede omitirlo, pero es tan trivial incluir un escape adecuado que no hay una buena razón para evitarlo.

Douglas
fuente
0

Si realmente estás hablando del texto estático

<title>Foo & Bar</title>

almacenado en algún archivo en el disco duro y servido directamente por un servidor, entonces sí: probablemente no necesite escapar.

Sin embargo, dado que actualmente hay muy poco contenido HTML que sea completamente estático, agregaré el siguiente descargo de responsabilidad que asume que el contenido HTML se genera a partir de alguna otra fuente (contenido de la base de datos, entrada del usuario, resultado de la llamada al servicio web, resultado API heredado). ..):

Si no escapar de un simple &, entonces es probable que usted también no escapar de un &amp;o una &nbsp;o <b>o <script src="http://attacker.com/evil.js">o cualquier otro texto válido. Eso significaría que, en el mejor de los casos, muestra su contenido incorrectamente y es más probable que sea sospechoso de ataques XSS .

En otras palabras: cuando ya está comprobando y escapando de los otros casos más problemáticos, casi no hay razón para dejar al independiente, no totalmente roto, pero aún un tanto sospechoso, y sin escapes.

Joachim Sauer
fuente
2
No voté en contra pero, si tuviera que adivinar, diría que fue rechazado porque su respuesta (aunque inteligente) no coincide con la pregunta. No está preguntando por escapar de la entrada del usuario. Él tiene control sobre los personajes y básicamente pregunta "Si hace lo que quiero, ¿es realmente importante seguir las especificaciones del idioma al pie de la letra?" Es decir, él sabe que hay un & porque lo puso.
Matt
@ Matt: Ya veo, y eso sería razonable. Solo estaba asumiendo que ya nadie escribe páginas HTML completamente estáticas y que casi todo el contenido es al menos algo dinámico (generalmente basado en algún contenido de base de datos). Quizás esa suposición debería haberse hecho explícita.
Joachim Sauer
-1

No estoy seguro de si esto es útil para alguien ... Estuve luchando contra esto por un tiempo ... aquí hay una gloriosa expresión regular que puede usar para arreglar todos sus enlaces, javascript, contenido. Tuve que lidiar con un montón de contenido heredado que nadie quería corregir.

Agregue esto a su anulación de Render en su página maestra o control:

Por favor, no me critiques por poner esto en el lugar equivocado:

// remove the & from href="blaw?a=b&b=c" and replace with &amp; 
//in urls - this corrects any unencoded & not just those in URL's
// this match will also ignore any matches it finds within <script> blocks AND
// it will also ignore the matches where the link includes a javascript command like
// <a href="javascript:alert{'& & &'}">blaw</a>
html = Regex.Replace(html, "&(?!(?<=(?<outerquote>[\"'])javascript:(?>(?!\\k<outerquote>|[>]).)*)\\k<outerquote>?)(?!(?:[a-zA-Z][a-zA-Z0-9]*|#\\d+);)(?!(?>(?:(?!<script|\\/script>).)*)\\/script>)", "&amp;", RegexOptions.Singleline | RegexOptions.IgnoreCase);
Richard Dufour
fuente
-1

El enlace tiene un ejemplo bastante bueno de cuándo y por qué es posible que deba escapar &a&amp;

https://jsfiddle.net/vh2h7usk/1/

Curiosamente, tuve que escapar del personaje para representarlo correctamente en mi respuesta aquí. Si tuviera que usar la opción de muestra de código incorporada (desde el panel de respuesta), simplemente podría escribir &amp;y aparece como debería. Pero si tuviera que usar manualmente el <code></code>elemento, entonces tendría que escapar para representarlo correctamente :)

mathin
fuente