Eu realmente preciso codificar '&' como '& amp;'?

207

Estou usando um &símbolo ' ' com HTML5 e UTF-8 no meu site <title>. O Google mostra muito bem oe comercial em seus SERPs, assim como todos os navegadores em seus títulos.

http://validator.w3.org está me dando o seguinte:

& não iniciou uma referência de personagem. (e provavelmente deveria ter escapado como &amp;.)

Eu realmente preciso fazer &amp;?

Não estou preocupado com a validação das minhas páginas, mas estou curioso para ouvir a opinião das pessoas sobre isso e se é importante e por que.

Haroldo
fonte
63
As especificações não dizem isso. O pôster refere-se ao HTML5, que não requer escape do e comercial em todos os cenários.
Matthew Wilson
2
Esse deve ser o Wiki da comunidade, pois você está procurando opiniões, e não ser exigente quanto à validação implica que não há base objetiva sobre a qual responder.
Richard JP Le Guen
6
@ Richard: realmente? Embora eu não concorde que "a validação não importa", vejo isso como uma pergunta muito objetiva: "isso quebra algo diferente das especificações?"
Joachim Sauer
2
@YiJiang Os navegadores da web atuais se esforçam ao máximo para entender o usuário . E o Google também . Faz parte do Spec. Os futuros navegadores da web podem ser menos tolerantes. Portanto, é sempre uma boa ideia verificar como a Wikipedia faz e copiá-las.
unixman83
2
A especificação HTML diz para aceitar entrada porcaria. Isso significa que seu site está "autorizado" a ser uma porcaria agora? Feche as tags que precisam ser fechadas e evite coisas! Vamos lá pessoal.
precisa saber é o seguinte

Respostas:

143

Sim. Assim como o erro disse, em HTML, os atributos são #PCDATA, o que significa que são analisados. Isso significa que você pode usar entidades de caracteres nos atributos. O uso &por si só está errado e, se não for em navegadores brandos, e o fato de ser HTML e não XHTML, interromperia a análise. Apenas escape como &amp;tudo ficaria bem.

O HTML5 permite deixá-lo sem escape, mas apenas quando os dados a seguir não parecem uma referência de caractere válida. No entanto, é melhor escapar de todas as instâncias desse símbolo do que se preocupar com quais e quais não devem ser.

Mantenha esse ponto em mente; se você não está escapando do & para o & amp;, é ruim o suficiente para os dados que você cria (onde o código pode muito bem ser inválido), também não pode estar escapando dos delimitadores de tags, que é um grande problema para os dados enviados pelo usuário, o que poderia muito bem levar à injeção de HTML e scripts, roubo de cookies e outras explorações.

Por favor, apenas escape do seu código. Isso poupará muitos problemas no futuro.

Delan Azabani
fonte
9
Nenhum navegador jamais interpretará mal um & por si só. Todo navegador existente o exibe como "&". Considerando que ele explicitamente pediu razão prática para fazê-lo, e que ele afirmou que não se preocupa com a validação ..
Thomas Bonini
47
Sim. Mas moralmente, devemos confiar na indulgência e no tratamento "agradável" dos navegadores? Ou devemos apenas escrever o código correto?
Delan Azabani 16/08
8
@ Delan: enquanto eu tento validar todas as páginas que escrevo, entendo ao ler sua pergunta que ele não se importa "moralmente". Ele só se importa se funciona ou não. São duas filosofias diferentes e ambas têm seus prós e contras, e não há uma "correta". Por exemplo, este site não valida e, no entanto, é um ótimo site.
Thomas Bonini
3
@ Andreas, mas os navegadores têm bugs suficientes na maneira como interpretam o código correto, dependendo deles obterem os resultados corretos quando você os envia uma marcação sem sentido é arriscado. Ela pode trabalhar hoje, com esse exemplo, e depois falhar com o seguinte exemplo (dizer se o seguinte exemplo tem um lugar-e-vírgula após o &)
Jon Hanna
11
Todo mundo parece estar falando sobre HTML5, mas a pergunta original afirma que o HTML5 está em uso. O HTML5 permite explicitamente um & sem escape & nesta situação, a menos que o que se segue & normalmente seja expandido para uma entidade (por exemplo, & copy = 2 é problemático, mas & x = 2 está correto).
Matthew Wilson
55

Validação à parte, permanece o fato de que a codificação de certos caracteres é importante para um documento HTML, para que ele possa ser renderizado de maneira adequada e segura como uma página da web.

Codificar &como &amp;em todas as circunstâncias, para mim, é uma regra mais fácil de seguir, reduzindo a probabilidade de erros e falhas.

Compare o seguinte: qual é mais fácil? o que é mais fácil de fazer ?

Metodologia 1

  1. Escreva algum conteúdo que inclua caracteres e comerciais.
  2. Codifique todos eles.

Metodologia 2

(com um grão de sal, por favor;))

  1. Escreva algum conteúdo que inclua caracteres e comercial.
  2. Caso a caso, observe cada e comercial. Determine se:
    • É isolado e, como tal, sem ambiguidade, um e comercial. por exemplo. volt & amp
       > Nesse caso, não se preocupe em codificá-lo.
    • Não é isolado, mas você sente que não deixa de ser ambíguo, pois a entidade resultante não existe e nunca existirá, pois a lista de entidades nunca poderia evoluir. Por exemplo, amp&volt
       nesse caso, não se preocupe em codificá-lo.
    • Não é isolado e ambíguo. por exemplo. volt&amp
       > Codifique.

??

Richard JP Le Guen
fonte
3
O segundo caso de amp&volt é ambíguo: &voltagora é uma referência de entidade ou não?
Gumbo
6
@ Gumbo O E comercial nãoamp&volt é um E comercial ambíguo (conforme a definição na especificação HTML). Consulte mathiasbynens.be/notes/ambiguous-ampersands e mothereff.in/ampersands#amp%26volt .
Mathias Bynens
@MathiasBynens Até agora (2019), a definição de um e comercial ambíguo parece ter mudado um pouco da definição citada em 2011 em mathiasbynens.be/notes/ambiguous-ampersands .
Jacob C. disse Reinstate Monica
21

As regras HTML5 são diferentes do HTML4. Não é necessário no HTML5, a menos que o e comercial pareça iniciar um nome de parâmetro. "& copy = 2" ainda é um problema, por exemplo, uma vez que o & copy; é o símbolo de direitos autorais.

No entanto, parece-me que é um trabalho mais difícil decidir codificar ou não codificar, dependendo do texto a seguir. Portanto, o caminho mais fácil é provavelmente codificar o tempo todo.

Matthew Wilson
fonte
2
É como citar valores de atributos - você não precisa, mas não pode errar se fizer isso o tempo todo.
Paul D. Waite
3
&copy=2não é um problema tão grande quanto você imagina. Em valores de atributo (por exemplo, o hrefatributo), o &copyitem não será considerado uma referência de caractere ©. Fora de um valor de atributo, seria.
Mathias Bynens
Dado que um e comercial é normalmente precedido e seguido por um espaço no texto em inglês, não é difícil lembrar ou pensar na regra que sigo: Se o e comercial não estiver tocando outro caractere visível, o que é quase sempre, não é necessário codificação. Caso contrário, apenas codifique por uma questão de simplicidade.
Carl Smith
Você poderia adicionar uma referência às regras do HTML5?
Ferrybig
17

Eu acho que isso se transformou em mais uma questão de "por que seguir as especificações quando o navegador não se importa". Aqui está a minha resposta generalizada:

Os padrões não são "presentes". Eles são uma coisa "futura". Se nós, como desenvolvedores, seguirmos os padrões da Web, é mais provável que os fornecedores de navegadores os implementem corretamente, e nos aproximaremos de uma Web completamente interoperável, onde hacks CSS, detecção de recursos e detecção de navegador não são necessários. Onde não precisamos descobrir por que nossos layouts quebram em um navegador específico ou como contornar isso.

Especificamente, se o HTML5 não exigir o uso do & amp; em sua situação específica e usando um doctype HTML5 (e também esperando que seus usuários usem navegadores compatíveis com HTML5), não há motivo para fazê-lo.

Ryan Kinal
fonte
1
Com isso dito, de um modo geral, você deve lembrar que a maioria das formas "padrão" ainda estão no modo de rascunho e podem mudar no futuro.
refaelio 26/06
6

Bem, se vier da entrada do usuário, então absolutamente sim, por razões óbvias. Pense se este site não o fizesse: o título dessa pergunta apareceria como eu realmente preciso codificar '&' como '&'?

Se é apenas algo assim echo '<title>Dolce & Gabbana</title>';, estritamente falando, você não precisa. Seria melhor, mas se você não fizer isso, nenhum usuário perceberá a diferença.

Thomas Bonini
fonte
5

Você poderia nos mostrar o que titlerealmente é? Quando eu envio

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

para http://validator.w3.org/ - solicitando explicitamente que ele use o modo experimental HTML 5 - não há queixas sobre o &...

AakashM
fonte
1
Sim, o HTML5 possui um analisador diferente dos analisadores HTML e XHTML anteriores e permite e comercial sem escape em determinadas situações.
kevinji
No que diz respeito a esses exemplos, isso não é novidade no HTML5. Ambos <title>Dolce & Gabbana</title>e <p>Dolce & Gabbana</p>são HTML 2.0 válidos.
Mathias Bynens
4

No HTML a &marca o início de uma referência, seja de uma referência de caractere ou de uma referência de entidade . A partir desse ponto, o analisador espera uma #referência de caractere ou um nome de entidade que indica uma referência de entidade, ambos seguidos por a ;. Esse é o comportamento normal.

Mas se o nome de referência ou apenas a abertura de referência &é seguido por um espaço em branco ou outros delimitadores como ", ', <, >, &, o fim ;e até mesmo uma referência para representar uma planície &pode ser omitido:

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

Somente nesses casos, o final ;ou até a própria referência podem ser omitidos (pelo menos no HTML 4). Eu acho que o HTML 5 requer o final ;.

Mas a especificação recomenda sempre usar uma referência como a referência de caractere &#38;ou a referência de entidade &amp;para evitar confusão:

Os autores devem usar " &amp;" (ASCII decimal 38) em vez de " &" para evitar confusão com o início de uma referência de caractere (delimitador aberto de referência de entidade). Os autores também devem usar " &amp;" nos valores de atributo, pois referências de caracteres são permitidas nos valores de atributo CDATA.

quiabo
fonte
1
Essa é a especificação do HTML 4 à qual você vincula; da minha leitura da especificação HTML 5 (rascunho), apenas e comerciais ambíguos não são permitidos. Um e comercial seguido por um espaço, por exemplo, não é ambíguo e, portanto, (novamente pela minha leitura) deve ser permitido - veja minha resposta para a marcação que o validador HTML 5 aceita.
precisa saber é o seguinte
1
@AakashM: Não tenho certeza, parecia assim.
Gumbo
3

Se o usuário o transmitir para você ou ele acabar em um URL, você precisará escapar dele.

Se ele aparecer em texto estático em uma página? Todos os navegadores acertarão este caminho de qualquer maneira, não se preocupe muito, pois ele funcionará.

Dean J
fonte
3

Atualização (março de 2020): o validador do W3C não se queixa mais de escape de URLs.

Eu estava verificando por que o URL da imagem precisa escapar e, portanto, tentei em https://validator.w3.org . A explicação é bem legal. Ele destaca que mesmo os URLs precisam ser escapados. [PS: Eu acho que ele não escapou quando consumido desde a necessidade da URL &. Alguém pode esclarecer?]

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

Uma referência de entidade foi encontrada no documento, mas não há nenhuma referência com esse nome definido. Geralmente, isso é causado por erros de ortografia do nome de referência, e comercial não codificado ou por deixar o ponto e vírgula à direita (;). A causa mais comum desse erro é um e comercial não codificado em URLs, conforme descrito pelo WDG em "E comercial em URLs". As referências de entidade começam com um e comercial (&) e terminam com um ponto-e-vírgula (;). Se você deseja usar um e comercial literal no seu documento, você deve codificá-lo como "&" (mesmo dentro de URLs!). Cuidado para encerrar as referências de entidade com um ponto-e-vírgula ou sua referência de entidade pode ser interpretada em conexão com o texto a seguir. Lembre-se também de que as referências de entidades nomeadas diferenciam maiúsculas de minúsculas; & Aelig; e æ são caracteres diferentes.

Nishant
fonte
1
Leia a resposta mais votada. Os atributos são #PCDATA e, portanto, analisados. As entidades são tratadas lá. No seu exemplo, o &inicia uma referência de entidade. Após a leitura &qux, o analisador não encontra ponto e vírgula final ( ;), mas executa um sinal de igual ( =), que não pode fazer parte do nome da entidade. Isso deve ser um erro de análise, se o analisador tentar ser realmente rigoroso (de acordo com o HTML 4). No HTML 5, a análise de entidades é geralmente mais relaxada.
Palec
1
Eu suspeito que, em geral, é melhor usar ;como um separador nas seqüências de caracteres de consulta (quando você controla o link) por esse motivo.
Demi
2

Sim, você deve tentar fornecer código válido, se possível.

A maioria dos navegadores corrige esse erro silenciosamente, mas há um problema em confiar na manipulação de erros nos navegadores. Não existe um padrão para lidar com códigos incorretos; portanto, cabe a cada fornecedor de navegador tentar descobrir o que fazer com cada erro, e os resultados podem variar.

Alguns exemplos em que os navegadores provavelmente reagirão de maneira diferente são se você colocar elementos dentro de uma tabela, mas fora das células da tabela, ou se aninhar links dentro um do outro.

Para o seu exemplo específico, não é provável que cause problemas, mas a correção de erros no navegador pode, por exemplo, fazer com que o navegador mude do modo compatível com os padrões para o modo quirks, o que pode fazer com que seu layout seja completamente quebrado.

Portanto, você deve corrigir erros como este no código, caso contrário, para manter a lista de erros no validador curta, para detectar problemas mais sérios.

Guffa
fonte
2

Há alguns anos, recebemos um relatório de que um de nossos aplicativos da web não estava sendo exibido corretamente no Firefox. Verificou-se que a página continha uma tag que parecia

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

Quando confrontado com um atributo de estilo repetido, o IE combina os dois estilos, enquanto o Firefox usa apenas um deles, daí o comportamento diferente. Eu mudei a tag para

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

e com certeza, corrigiu o problema! A moral da história é que os navegadores têm um tratamento mais consistente do HTML válido do que do HTML inválido. Então, corrija sua maldita marcação! (Ou use o HTML Tidy para corrigi-lo.)

dan04
fonte
1

se &for usado em html , você deve escapar dele

Se &for usado em strings javascript, por exemplo, um alert('This & that');ou document.href, você não precisará usá-lo.

Se você estiver usando document.write, deverá usá-lo, por exemplo document.write(<p>this &amp; that</p>)

Alex
fonte
document.writeDeveria ser evitado. Consulte a caixa de aviso em w3.org/html/wg/drafts/html/master/dom.html#document.write%28%29
Oriol
Bom ponto sobre document.write(). Mas o ponto principal de Alex é escrever sobre o documento a partir de suportes de script. 1
Patrick M
1

Depende da probabilidade de um ponto-e-vírgula terminar próximo ao seu &, fazendo com que ele exiba algo bem diferente.

Por exemplo, ao lidar com informações de usuários (por exemplo, se você incluir o assunto de uma postagem no fórum fornecida pelo usuário em suas tags de título), nunca saberá onde eles podem estar colocando ponto-e-vírgula aleatório e poderá exibir entidades estranhas aleatoriamente. Portanto, sempre escape nessa situação.

Para seu próprio html estático, com certeza, você pode ignorá-lo, mas é tão trivial incluir uma fuga adequada, que não há boas razões para evitá-lo.

Douglas
fonte
0

Se você está realmente falando sobre o texto estático

<title>Foo & Bar</title>

armazenado em algum arquivo no disco rígido e servido diretamente por um servidor, então sim: provavelmente não precisa ser escapado.

No entanto, como atualmente há muito pouco conteúdo HTML totalmente estático, adicionarei o seguinte aviso de isenção de responsabilidade que pressupõe que o conteúdo HTML seja gerado a partir de outra fonte (conteúdo do banco de dados, entrada do usuário, resultado da chamada de serviço da Web, resultado da API herdada). ..):

Se você não escapar de um simples &, então as chances são que você também não escapar de uma &amp;ou de um &nbsp;ou <b>ou <script src="http://attacker.com/evil.js">ou qualquer outro texto inválido. Isso significa que, na melhor das hipóteses, você está exibindo seu conteúdo incorretamente e é mais provável que seja suspeito de ataques XSS .

Em outras palavras: quando você já está verificando e escapando dos outros casos mais problemáticos, quase não há razão para deixar o não-totalmente-quebrado-mas-ainda-um-peixe-autônomo- e sem escape.

Joachim Sauer
fonte
2
Eu não diminuí o voto, mas, se eu tivesse que adivinhar, diria que você foi prejudicado porque sua resposta (embora inteligente) é um pouco incompatível com a pergunta. Ele não está perguntando sobre como escapar da entrada do usuário. Ele tem controle sobre os personagens e está basicamente perguntando "Se faz o que eu quero, é realmente importante seguir as especificações do idioma conforme a letra?" Ou seja, ele sabe que há um & porque ele colocá-lo.
Matt
@ Matt: Entendo, e isso seria razoável. Eu estava assumindo que ninguém mais escreve páginas HTML totalmente estáticas e que praticamente todo o conteúdo é pelo menos um pouco dinâmico (geralmente com base em algum conteúdo do banco de dados). Talvez essa suposição devesse ter sido explicitada.
Joachim Sauer
-1

não tenho certeza se isso é útil para alguém ... Eu estava lutando contra isso por um tempo ... aqui está um regex glorioso que você pode usar para corrigir todos os seus links, javascript, conteúdo. Eu tive que lidar com uma tonelada de conteúdo herdado que ninguém queria corrigir.

Adicione isso à sua substituição Render na sua página mestre ou controle:

Por favor, não me chame por colocar isso no lugar errado:

// 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
fonte
-1

O link tem um bom exemplo de quando e por que você pode precisar fugir &para&amp;

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

Curiosamente, eu tive que escapar do personagem para representá-lo corretamente em minha resposta aqui. Se eu usar a opção de amostra de código embutida (no painel de respostas), basta digitar &amp;e ela aparece como deveria. Mas se eu fosse usar manualmente o <code></code>elemento, teria que escapar para representá-lo corretamente :)

mathin
fonte