¿Codifico ampersands en <a href…>?

157

Estoy escribiendo código que genera HTML automáticamente, y quiero que codifique las cosas correctamente.

Digamos que estoy generando un enlace a la siguiente URL:

http://www.google.com/search?rls=en&q=stack+overflow

Supongo que todos los valores de los atributos deben estar codificados en HTML. (Corríjame si me equivoco). Eso significa que si estoy colocando la URL anterior en una etiqueta de anclaje, debería codificar el ampersand como &amp;, así:

<a href="http://www.google.com/search?rls=en&amp;q=stack+overflow">

¿Es eso correcto?

JW
fuente
posible duplicado de ¿Qué caracteres hacen inválida una URL?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
66
@CiroSantilli: se trata de cadenas de URL reales; Se trata de cómo se codifican cuando aparecen en los atributos HTML.
JW.
como veo, no siempre se requiere codificar símbolos en html5, y las respuestas están desactualizadas.
qdinar
1
pregunta para html5: stackoverflow.com/questions/19441750/…
qdinar

Respuestas:

175

Sí lo es. Las entidades HTML se analizan dentro de los atributos HTML, y un extravío &crearía una ambigüedad. Es por eso que siempre debe escribir en &amp;lugar de solo &dentro de todos los atributos HTML.

Dicho esto, solo las &comillas deben codificarse. Si tiene caracteres especiales como éen su atributo, no necesita codificarlos para satisfacer el analizador HTML.

Solía ​​ser el caso de que las URL necesitaran un tratamiento especial con caracteres no ASCII, como é. Tenías que codificar aquellos que usaban porcentajes de escape, y en este caso daría %C3%A9, porque fueron definidos por RFC 1738 . Sin embargo, RFC 1738 ha sido reemplazado por RFC 3986 (URI, identificadores uniformes de recursos) y RFC 3987 (IRI, identificadores de recursos internacionalizados), en los que WhatWG basó su trabajo para definir cómo deben comportarse los navegadores cuando ven una URL con un código no ASCII personajes en él desde HTML5 . Por lo tanto, ahora es seguro incluir caracteres que no sean ASCII en las URL, con codificación de porcentaje o no.

zneak
fuente
1
Estaba bastante seguro de esto, pero tuve un raro momento de duda. Gracias por confirmar.
JW.
1
También puede codificar espacios como "+" en lugar de% 20, lo que hace que la URL sea más fácil de leer.
NickG
1
+ no se respeta en los enlaces de mailto en el cliente de correo nativo de iPhone actualmente, por lo que vale.
Ryan Olson
1
étodavía necesita codificación: stackoverflow.com/questions/2742852/unicode-characters-in-urls
lulalala
44
Agregaría (ya que acabo de caer en este error) que si confía en un motor de plantillas, debe verificar si eso se encarga automáticamente de escapar de las entidades HTML o no. En mi caso, Twig estaba haciendo eso, y yo estaba escapando erróneamente de la escritura &amp;en el atributo de etiqueta en lugar de usarlo directamente &.
Kamafeather
24

Según las recomendaciones HTML oficiales actuales, el ampersand debe escaparse, por ejemplo, &amp;en contextos como este. Sin embargo, los navegadores no lo requieren, y HTML5 CR propone hacer de esto una regla , de modo que se apliquen reglas especiales en los valores de los atributos. Los validadores HTML5 actuales están desactualizados a este respecto (consulte el informe de errores con comentarios).

Seguirá siendo posible escapar de los símbolos en los valores de los atributos, pero aparte de la validación con las herramientas actuales, no hay necesidad práctica de escapar de ellos en los hrefvalores (y existe un pequeño riesgo de cometer errores si comienza a escapar de ellos).

Jukka K. Korpela
fuente
44
Sin embargo, XHTML (XHTML real enviado como application/xhtml+xml) probablemente siempre lo requiera.
zneak
44
Una advertencia a este cambio, que todavía se está discutiendo, debatiendo y malentendiendo, es que &se supone que está bien ahora, siempre y cuando sea " poco ambiguo". Una forma obvia de hacer que el ampersand sea ambiguo es seguirlo primero con caracteres no espaciales y luego con un punto y coma. Ese signo es ahora ambiguo, y se causar un error de análisis.
Matty
Como dijo Jukka, ciertamente existe el riesgo de codificar todos los símbolos de unión, así que considere qué tan probable es que una de sus urls href contenga un punto y coma. Es bastante improbable, ya que no estoy seguro de haber visto una url con punto y coma. No es que no se pueda hacer. Hablando prácticamente, no creo que sea probable que nuestro uso de &sea ​​ambiguo. Por lo tanto, continuamos usándolo sin codificar en los atributos href.
Matty
Toda la razón por la que es necesario escapar es precisamente por la posibilidad de una ambigüedad . Es posible que este problema en particular no sea la introducción de vectores de ataque XSS, mala representación o ningún efecto en el 99.99% del tiempo, pero esa no es una razón para no molestarse. Es difícil escapar correctamente y siempre existe la posibilidad de cometer errores.
Phil
5

Estoy publicando una nueva respuesta porque encuentro que la respuesta de zneak no tiene suficientes ejemplos, no muestra el manejo de HTML y URI como diferentes aspectos y estándares y faltan algunas cosas menores.

Tiene dos estándares con respecto a las URL en los enlaces ( <a href).

El primer estándar es RFC 1866 (HTML 2.0) donde en "3.2.1. Caracteres de datos" puede leer los caracteres que deben escaparse cuando se usan como valor para un atributo HTML. (Los atributos en sí mismos no permiten caracteres especiales, por ejemplo, <a hr&ef="http://...no está permitido ni lo está <a hr&amp;ef="http://...).

Más tarde, esto se ha incorporado al estándar HTML 4 , los caracteres que necesita para escapar son:

<   to   &lt;
>   to   &gt;
&   to   &amp;
"   to   &quote;
'   to   &apos;

El otro estándar es RFC 3986 "Estándar genérico de URI", donde se manejan las URL (esto sucede cuando el navegador está a punto de seguir un enlace porque el usuario hizo clic en el elemento HTML).

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Es importante escapar de esos caracteres para que el cliente sepa si representan datos o un delimitador.

Ejemplo sin escapes:

https://example.com/?user=test&password&te&st&goto=https://google.com

Ejemplo, URL totalmente legítima

https://example.com/?user=test&password&te%26st&goto=https%3A%2F%2Fgoogle.com

Ejemplo de URL totalmente legítima en el valor del atributo HTML:

https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com

También escenarios importantes:

  • Javascript como valor:

    <img src="..." onclick="window.location.href = &quot;https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com&quot;;">...</a>(Sí, ;;es correcto)

  • JSON como valor:

    <a href="..." data-analytics="{&quot;event&quot;: &quot;click&quot;}">...</a>

  • Cosas escapadas dentro de cosas escapadas, doble codificación, URL dentro de URL dentro de parámetro, etc., ...

    http://x.com/?passwordUrl=http%3A%2F%2Fy.com%2F%3Fuser%3Dtest&amp;password=&quot;&quot;123

Daniel W.
fuente
3

Sí, debes convertirte &a &amp;.

Esta herramienta de validación html de W3C es útil para preguntas como esta. Le informará los errores y advertencias de una página en particular.

Randy Greencorn
fuente
1
No estoy seguro de que el validador W3C detecte esto (sin escape &en un href) como un error.
ChrisW
66
Actualmente, el validador W3C acepta sin escapes y como válido. ¿Significa que el estándar ha cambiado y la codificación ya no es necesaria? (haciendo la mayoría de las respuestas obsoletas aquí)? Si es así, ¿esto se aplica solo a href o cualquier atributo?
matteo