Czy naprawdę muszę kodować „&” jako „& amp;”?

207

&W mojej witrynie używam symbolu „ ” z HTML5 i UTF-8 <title>. Google pokazuje ampersand dobrze na swoich SERP, podobnie jak wszystkie przeglądarki w swoich tytułach.

http://validator.w3.org daje mi to:

i nie rozpoczął odniesienia do znaku. (i prawdopodobnie powinienem uciec jako &amp;.)

Czy naprawdę muszę to zrobić &amp;?

Nie przejmuję się tym, że moje strony sprawdzają poprawność ze względu na sprawdzanie poprawności, ale jestem ciekawy opinii ludzi na ten temat oraz czy jest to ważne i dlaczego.

Haroldo
źródło
63
Specyfikacje tego nie mówią. Plakat odnosi się do HTML5, który nie wymaga ucieczki przed ampersandem we wszystkich scenariuszach.
Matthew Wilson,
2
Powinna to być Wiki społeczności, ponieważ szukasz opinii, a nie wybredna walidacja oznacza, że ​​nie ma obiektywnych podstaw do odpowiedzi.
Richard JP Le Guen
6
@Richard: naprawdę? Chociaż nie zgadzam się z tym, że „sprawdzanie poprawności nie ma znaczenia”, widzę to jako bardzo obiektywne pytanie: „czy to łamie coś innego niż specyfikację?”
Joachim Sauer
2
@YiJiang Aktualne przeglądarki starają się zrozumieć użytkownika . Podobnie Google . Jest to część specyfikacji. Przyszłe przeglądarki internetowe mogą być mniej wybaczające. Dlatego zawsze warto sprawdzić, jak robi to Wikipedia, i skopiować je.
unixman83,
2
Specyfikacja HTML mówi, aby akceptować bzdury. Czy to oznacza, że ​​Twoja witryna może teraz „być bzdurą”? Zamknij tagi, które należy zamknąć i uciec od rzeczy! Dajcie spokój ludzie.
doug65536,

Odpowiedzi:

143

Tak. Tak jak powiedział błąd, w HTML atrybuty to #PCDATA, co oznacza, że ​​zostały przeanalizowane. Oznacza to, że możesz używać encji znakowych w atrybutach. Używanie &samo w sobie jest niewłaściwe, a jeśli nie dla łagodnych przeglądarek, a fakt, że jest to HTML, a nie XHTML, przerwałby analizę. Po prostu uciekaj jak &amp;i wszystko będzie dobrze.

HTML5 pozwala na pozostawienie go bez zmian, ale tylko wtedy, gdy następujące dane nie wyglądają jak prawidłowe odwołania do znaków. Jednak lepiej jest po prostu uciec od wszystkich wystąpień tego symbolu, niż martwić się, które powinny być, a które nie.

Miej to na uwadze; jeśli nie uciekasz & do & amp ;, jest wystarczająco zły dla danych, które tworzysz (gdzie kod może być bardzo nieprawidłowy), możesz również nie uciekać z ograniczników tagów, co jest ogromnym problemem dla danych przesyłanych przez użytkowników, co może bardzo dobrze prowadzić do wstrzykiwania HTML i skryptów, kradzieży plików cookie i innych exploitów.

Po prostu uniknij kodu. Zaoszczędzi ci to wielu kłopotów w przyszłości.

Delan Azabani
źródło
9
Żadna przeglądarka nigdy nie „źle zinterpretuje” a & sama w sobie. Każda istniejąca przeglądarka wyświetla to jako „&”. Biorąc pod uwagę, że wyraźnie poprosił o praktyczny powód, aby to zrobić, i stwierdził, że nie zależy mu na walidacji.
Thomas Bonini
47
Tak. Ale moralnie, czy powinniśmy polegać na łagodności i „miłej” obsłudze błędów w przeglądarkach? A może powinniśmy pisać poprawny kod?
Delan Azabani,
8
@Delan: chociaż staram się, aby każda strona, którą piszę, jest poprawna, po przeczytaniu jego pytania rozumiem, że nie obchodzi go „moralnie”. Dba tylko, czy to działa, czy nie. Są to dwie różne filozofie, obie mają swoje zalety i wady, i nie ma „poprawnej”. Na przykład ta strona nie sprawdza poprawności, a mimo to jest świetna.
Thomas Bonini,
3
@Andreas, ale przeglądarki mają wystarczająco dużo błędów w interpretacji poprawnego kodu, w zależności od tego, czy uzyskują prawidłowe wyniki, gdy wysyłasz im bezsensowne znaczniki, to przypadek. Może działać dzisiaj z tym przykładem, a następnie zawieść z kolejnym przykładem (powiedz, jeśli następny przykład ma średnik gdzieś po znaku &)
Jon Hanna
11
Wydaje się, że wszyscy mówią o HTML5, ale oryginalne pytanie mówi, że HTML5 jest w użyciu. HTML5 wyraźnie zezwala na nieskalowanie i w tej sytuacji, chyba że następujące czynności i normalnie rozwiną się w byt (np. & Copy = 2 jest problematyczne, ale & x = 2 jest w porządku).
Matthew Wilson,
55

Pomijając walidację, pozostaje faktem, że kodowanie niektórych znaków jest ważne dla dokumentu HTML, aby mógł poprawnie i bezpiecznie renderować się jako strona internetowa.

Kodowanie, &tak jak &amp;we wszystkich okolicznościach, jest dla mnie łatwiejszą zasadą życia, zmniejszając prawdopodobieństwo błędów i niepowodzeń.

Porównaj następujące: co jest łatwiejsze? co jest łatwiejsze do zrobienia ?

Metodologia 1

  1. Napisz treść zawierającą znaki handlowe i handlowe.
  2. Zakoduj je wszystkie.

Metodologia 2

(proszę o ziarno soli;))

  1. Napisz treść zawierającą znaki handlowe i handlowe.
  2. W poszczególnych przypadkach spójrz na każdy znak ampersand. Ustal, czy:
    • Jest izolowany i jako taki jednoznacznie jest znakiem handlowego. na przykład. volt & amp
       > W takim przypadku nie zawracaj sobie głowy kodowaniem.
    • Nie jest izolowany, ale czujesz, że mimo to jest jednoznaczny, ponieważ wynikowa istota nie istnieje i nigdy nie będzie istnieć, ponieważ lista jednostek nigdy nie mogłaby się rozwijać. np. amp&volt
       > W takim przypadku nie zawracaj sobie głowy kodowaniem.
    • Nie jest odizolowany i niejednoznaczny. na przykład. volt&amp
       > Zakoduj to.

??

Richard JP Le Guen
źródło
3
Drugi przypadek amp&volt jest niejednoznaczny: czy &voltteraz jest odniesieniem do encji, czy nie?
Gumbo,
6
@Gumbo Znak & w amp&voltjest nie niejednoznaczne handlowe i (zgodnie z definicją w specyfikacji HTML). Zobacz mathiasbynens.be/notes/ambiguous-ampersands i mothereff.in/ampersands#amp%26volt .
Mathias Bynens
@MathiasBynens Do tej pory (2019) wydaje się , że definicja niejednoznacznego znaku handlowego i zmieniła się nieco w porównaniu z definicją cytowaną w 2011 r. W mathiasbynens.be/notes/ambiguous-ampersands .
Jacob C. mówi Przywróć Monikę
21

Reguły HTML5 różnią się od HTML4. Nie jest to wymagane w HTML5 - chyba że znak ampersand wygląda tak, jakby zaczynał nazwę parametru. „& copy = 2” nadal stanowi problem, na przykład, ponieważ & copy; jest symbolem praw autorskich.

Wydaje mi się jednak, że trudniej jest zdecydować się na kodowanie lub nie, w zależności od następującego tekstu. Więc najłatwiejszą drogą jest prawdopodobnie kodowanie przez cały czas.

Matthew Wilson
źródło
2
To jak cytowanie wartości atrybutów - nie musisz, ale nie możesz się pomylić, jeśli robisz to cały czas.
Paul D. Waite
3
&copy=2nie jest tak dużym problemem, jak mogłoby się wydawać. W wartościach atrybutów (np. hrefAtrybut) &copynie będą one traktowane jako odwołanie do znaku dla ©. Poza wartością atrybutu tak by było.
Mathias Bynens
Biorąc pod uwagę, że znak ampersand jest zwykle poprzedzony spacją w tekście angielskim, nietrudno jest zapamiętać lub pomyśleć o zasadzie, którą stosuję: jeśli znak ampersand nie dotyka innej widocznej postaci, która jest prawie zawsze, to nie potrzebuje kodowanie. W przeciwnym razie po prostu koduj dla uproszczenia.
Carl Smith,
Czy możesz dodać odniesienie do reguł HTML5?
Ferrybig,
17

Myślę, że stało się to bardziej pytaniem „dlaczego stosować się do specyfikacji, kiedy przeglądarki to nie obchodzi”. Oto moja ogólna odpowiedź:

Normy nie są „obecne”. Są „przyszłością”. Jeśli my, jako programiści, przestrzegamy standardów internetowych, wówczas dostawcy przeglądarek są bardziej skłonni do prawidłowego wdrożenia tych standardów i zbliżamy się do całkowicie interoperacyjnej sieci, w której włamania CSS, wykrywanie funkcji i wykrywanie przeglądarki nie są konieczne. Tam, gdzie nie musimy dowiedzieć się, dlaczego nasze układy psują się w konkretnej przeglądarce lub jak to obejść.

W szczególności, jeśli HTML5 nie wymaga użycia & amp; w konkretnej sytuacji i korzystasz z formatu HTML5 (a także oczekujesz, że użytkownicy będą korzystać z przeglądarek zgodnych z HTML5), nie ma powodu, aby to robić.

Ryan Kinal
źródło
1
Biorąc to pod uwagę, ogólnie rzecz biorąc, musisz pamiętać, że większość „standardowych” sposobów jest nadal w trybie roboczym i może ulec zmianie w przyszłości.
refaelio
6

Cóż, jeśli pochodzi z danych wejściowych użytkownika, to absolutnie tak, z oczywistych powodów. Pomyśl, jeśli sama witryna tego nie zrobiła: tytuł tego pytania pojawiłby się, ponieważ naprawdę muszę zakodować „&” jako „&”?

Jeśli to po prostu coś takiego, echo '<title>Dolce & Gabbana</title>';to mówiąc ściśle, nie musisz. Byłoby lepiej, ale jeśli nie, żaden użytkownik nie zauważy różnicy.

Thomas Bonini
źródło
5

Czy możesz nam pokazać, jaka jest twoja titlerzeczywistość? Kiedy przesyłam

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

na http://validator.w3.org/ - wyraźnie prosząc go o użycie eksperymentalnego trybu HTML 5 - nie ma żadnych skarg na &...

AakashM
źródło
1
Tak, HTML5 ma inny analizator składni niż poprzednie parsery HTML i XHTML i pozwala na stosowanie nieoznaczonych ampersand w określonych sytuacjach.
kevinji
Jeśli chodzi o te przykłady, to nic nowego w HTML5. Zarówno <title>Dolce & Gabbana</title>i <p>Dolce & Gabbana</p>obowiązują HTML 2.0.
Mathias Bynens
4

W HTML a &oznacza początek odwołania, albo odwołania do znaku, albo odwołania do encji . Od tego momentu analizator składni oczekuje albo #oznaczenia odwołania do znaku, albo nazwy encji oznaczającej odwołanie do encji, po których następuje zarówno ;. To jest normalne zachowanie.

Ale jeśli nazwa odniesienia lub po prostu otwarcie odniesienia &następuje białej przestrzeni lub innych ograniczników podoba ", ', <, >, &, zakończenie ;, a nawet odniesienia do reprezentowania równinę &można pominąć:

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

Tylko w tych przypadkach ;można pominąć zakończenie lub nawet sam odnośnik (przynajmniej w HTML 4). Myślę, że HTML 5 wymaga zakończenia ;.

Ale specyfikacja zaleca zawsze używać odwołania takiego jak odwołanie do znaku &#38;lub odwołanie do bytu, &amp;aby uniknąć pomyłek:

Autorzy powinni użyć „ &amp;” (dziesiętnie ASCII 38) zamiast „ &”, aby uniknąć pomyłki z początkiem odwołania do znaku (otwarty separator encji). Autorzy powinni również używać „ &amp;” w wartościach atrybutów, ponieważ odwołania do znaków są dozwolone w ramach wartości atrybutów CDATA.

Gumbo
źródło
1
To jest specyfikacja HTML 4, do której linkujesz; z mojego czytania (szkicowej) specyfikacji HTML 5, niedopuszczalne są tylko dwuznaczne znaki handlowe. Na przykład znak ampersand, po którym następuje spacja, nie jest dwuznaczny, więc (ponownie poprzez czytanie) powinien być dozwolony - zobacz moją odpowiedź dotyczącą znaczników, którą akceptuje walidator HTML 5.
AakashM
1
@AakashM: Nie jestem pewien, to tak brzmiało.
Gumbo,
3

Jeśli użytkownik przekaże go tobie lub skończy w adresie URL, musisz go uciec.

Jeśli pojawia się w tekście statycznym na stronie? Wszystkie przeglądarki dostaną to w jedną stronę, nie martw się o to, ponieważ będzie działać.

Dziekan J.
źródło
3

Aktualizacja (marzec 2020): Walidator W3C nie narzeka już na ucieczkowe adresy URL.

Sprawdzałem, dlaczego URL obrazu musi uciekać, dlatego wypróbowałem go na https://validator.w3.org . Wyjaśnienie jest całkiem miłe. Podkreśla, że ​​nawet adresy URL wymagają zmiany znaczenia. [PS: Wydaje mi się, że nie zostanie usunięty, gdy zostanie zużyty, ponieważ potrzeba adresu URL &. Czy ktoś może to wyjaśnić?]

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

W dokumencie znaleziono odwołanie do jednostki, ale nie ma zdefiniowanego odwołania o tej nazwie. Często jest to spowodowane błędną pisownią nazwy odniesienia, niekodowanymi znakami ampersands lub pozostawieniem końcowego średnika (;). Najczęstszą przyczyną tego błędu są niezakodowane znaki handlowe w adresach URL, zgodnie z opisem WDG w „Ampersands w adresach URL”. Odwołania do encji zaczynają się od ampersandu (&) i kończą średnikiem (;). Jeśli chcesz użyć dosłownego znaku handlowego i w swoim dokumencie, musisz go zakodować jako „&” (nawet w adresach URL!). Uważaj, aby kończyć odwołania do encji średnikiem, ponieważ referencje encji mogą zostać zinterpretowane w związku z następującym tekstem. Należy również pamiętać, że w nazwanych odniesieniach encji rozróżniana jest wielkość liter; I Aelig; i… są ​​różnymi znakami.

Nishant
źródło
1
Przeczytaj najczęściej głosowaną odpowiedź. Atrybuty to #PCDATA i dlatego zostały przeanalizowane. Podmioty są tam obsługiwane. W twoim przykładzie &rozpoczyna się odwołanie do encji. Po odczytaniu &quxanalizator składni nie znajduje końcowego średnika ( ;), ale napotyka znak równości ( =), który nie może być częścią nazwy encji. Powinien to być błąd analizy składniowej, jeśli parser próbował być naprawdę ścisły (zgodnie z HTML 4). W HTML 5 parsowanie encji jest ogólnie bardziej zrelaksowane.
Palec,
1
Podejrzewam, że ogólnie z tego powodu najlepiej jest używać ;jako separatora w ciągach zapytań (gdy kontrolujesz łącze).
Demi
2

Tak, powinieneś spróbować podać poprawny kod, jeśli to możliwe.

Większość przeglądarek po cichu naprawi ten błąd, ale istnieje problem z poleganiem na obsłudze błędów w przeglądarkach. Nie ma standardu obsługi niepoprawnego kodu, więc każdy producent przeglądarki musi spróbować ustalić, co zrobić z każdym błędem, a wyniki mogą się różnić.

Niektóre przykłady, w których przeglądarki mogą zareagować inaczej, to umieszczenie elementów wewnątrz tabeli, ale poza komórkami tabeli lub zagnieżdżenie łączy między sobą.

W twoim konkretnym przykładzie prawdopodobnie nie spowoduje to żadnych problemów, ale korekcja błędów w przeglądarce może na przykład spowodować zmianę przeglądarki z trybu zgodnego ze standardami na tryb dziwactwa, co może spowodować całkowity awarię układu.

Powinieneś więc poprawić takie błędy w kodzie, jeśli nie w ogóle, aby lista błędów w walidatorze była krótka, abyś mógł dostrzec poważniejsze problemy.

Guffa
źródło
2

Kilka lat temu otrzymaliśmy raport, że jedna z naszych aplikacji internetowych nie wyświetlała się poprawnie w przeglądarce Firefox. Okazało się, że strona zawierała wyglądający tag

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

W obliczu atrybutu powtarzanego stylu IE łączy oba style, podczas gdy Firefox używa tylko jednego z nich, stąd różne zachowanie. Zmieniłem tag na

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

i na pewno to rozwiązało problem! Morał tej historii jest taki, że przeglądarki mają bardziej spójną obsługę prawidłowego HTML niż nieprawidłowego HTML. Więc napraw już swoje przeklęte znaczniki! (Lub użyj HTML Tidy, aby to naprawić.)

dan04
źródło
1

jeśli &jest używany w html , powinieneś go uciec

Jeśli &jest używany w ciągach javascript, np. alert('This & that');Lub document.href, nie musisz go używać.

Jeśli używasz document.write, powinieneś go użyć np document.write(<p>this &amp; that</p>)

Alex
źródło
document.writenależy unikać. Zobacz ostrzeżenie w w3.org/html/wg/drafts/html/master/dom.html#document.write%28%29
Oriol
Dobra uwaga na temat document.write(). Ale najważniejszy jest Alex, pisząc do dokumentu ze skryptów, imo. +1
Patrick M
1

Zależy to od prawdopodobieństwa, że ​​średnik znajdzie się w pobliżu &, powodując, że wyświetli coś zupełnie innego.

Na przykład, mając do czynienia z danymi wejściowymi od użytkowników (powiedzmy, jeśli umieścisz podany przez użytkownika temat postu na forum w tagach tytułu), nigdy nie wiesz, gdzie umieszczają losowe średniki, i może losowo wyświetlać dziwne byty. Więc zawsze uciekaj w takiej sytuacji.

W przypadku własnego statycznego html można go pominąć, ale tak proste jest włączenie prawidłowego ucieczki, że nie ma dobrego powodu, aby go unikać.

Douglas
źródło
0

Jeśli naprawdę mówisz o tekście statycznym

<title>Foo & Bar</title>

przechowywane w jakimś pliku na dysku twardym i podawane bezpośrednio przez serwer, a następnie tak: prawdopodobnie nie trzeba go uciekać.

Ponieważ jednak obecnie jest bardzo mało treści HTML, które są całkowicie statyczne, dodam następujące zastrzeżenie, które zakłada, że ​​treść HTML jest generowana z innego źródła (zawartość bazy danych, dane wejściowe użytkownika, wynik wywołania usługi internetowej, wynik API starszego typu,. ..):

Jeśli nie uciekać się proste &, to są szanse, również nie uciec &amp;lub &nbsp;lub <b>lub <script src="http://attacker.com/evil.js">lub inny nieważny tekst. Oznaczałoby to, że w najlepszym przypadku wyświetlasz niepoprawnie swoje treści i bardziej prawdopodobne jest, że podejrzewasz ataki XSS .

Innymi słowy: kiedy już sprawdzasz i unikasz innych, bardziej problematycznych przypadków, prawie nie ma powodu, aby pozostawić niezupełnie zepsuty, ale wciąż nieco podejrzany, samodzielny i niezamknięty.

Joachim Sauer
źródło
2
Nie głosowałem za głosem, ale gdybym musiał zgadywać, powiedziałbym, że zostałeś zagłosowany, ponieważ twoja odpowiedź (choć inteligentna) jest trochę niezgodna z pytaniem. Nie pyta o ucieczkę od danych wejściowych użytkownika. Ma kontrolę nad postaciami i zasadniczo pyta: „Jeśli robi to, co chcę, czy naprawdę ważne jest, aby stosować się do specyfikacji języka do litery?” Tzn. Wie, że jest i dlatego, że go włożył.
Matt
@Matt: Rozumiem, i to byłoby rozsądne. Po prostu zakładałem, że nikt już nie pisze całkowicie statycznych stron HTML i że prawie cała zawartość jest co najmniej nieco dynamiczna (zwykle oparta na zawartości bazy danych). Może to założenie powinno było zostać wyraźnie określone.
Joachim Sauer
-1

nie jestem pewien, czy jest to przydatne dla kogoś ... walczyłem z tym przez chwilę ... oto chwalebna regex, którego możesz użyć, aby naprawić wszystkie linki, javascript, treść. Musiałem poradzić sobie z mnóstwem starszych treści, których nikt nie chciał poprawić.

Dodaj to do zastąpienia renderowania na stronie wzorcowej lub kontrolce:

Proszę nie płonąć mną za umieszczenie tego w niewłaściwym miejscu:

// 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
źródło
-1

Łącze ma dość dobry przykład, kiedy i dlaczego może trzeba się uciec &do&amp;

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

Co ciekawe, musiałem uciec od postaci, aby odpowiednio ją przedstawić w mojej odpowiedzi tutaj. Jeśli miałbym użyć wbudowanej opcji przykładowego kodu (z panelu odpowiedzi), mogę po prostu wpisać &amp;i wygląda to tak, jak powinno. Ale jeśli miałbym ręcznie użyć tego <code></code>elementu, to muszę uciec, aby poprawnie go przedstawić :)

matematyka
źródło