Problemy z kodowaniem HTML - zamiast „& nbsp;” pojawia się znak „”


203

Mam starszą aplikację, która zaczyna się źle zachowywać, z jakiegokolwiek powodu nie jestem pewien. Generuje wiązkę HTML, która jest przekształcana w raporty PDF przez ActivePDF.

Proces działa w następujący sposób:

  1. Wyciągnij szablon HTML z bazy danych z tokenami do zastąpienia (np. „~ CompanyName ~”, „~ CustomerName ~” itp.)
  2. Zamień tokeny na prawdziwe dane
  3. Uporządkuj HTML za pomocą prostej funkcji regex, która właściwość formatuje wartości atrybutów znaczników HTML (zapewnia znaki cudzysłowu itp., Ponieważ silnik renderujący ActivePDF nienawidzi niczego oprócz pojedynczych cudzysłowów wokół wartości atrybutów)
  4. Wyślij kod HTML do serwisu internetowego, który tworzy plik PDF.

Gdzieś w tym bałaganie nieprzerwane spacje z szablonu (  ów) HTML są kodowane jako ISO-8859-1, dzięki czemu wyświetlają się niepoprawnie jako znak „” podczas przeglądania dokumentu w przeglądarce (FireFox). ActivePDF rzyga na te znaki spoza UTF8.

Moje pytanie: skoro nie wiem, skąd bierze się problem i nie mam czasu na jego zbadanie, czy istnieje prosty sposób na ponowne zakodowanie lub znalezienie i zastąpienie złych znaków? Próbowałem wysłać to przez tę małą funkcję, którą razem zrzuciłem, ale zamienia to wszystko w gobbledegook niczego nie zmienia.

Private Shared Function ConvertToUTF8(ByVal html As String) As String
    Dim isoEncoding As Encoding = Encoding.GetEncoding("iso-8859-1")
    Dim source As Byte() = isoEncoding.GetBytes(html)
    Return Encoding.UTF8.GetString(Encoding.Convert(isoEncoding, Encoding.UTF8, source))
End Function

Jakieś pomysły?

EDYTOWAĆ:

Na razie sobie z tym radzę, choć nie wydaje się to dobrym rozwiązaniem:

Private Shared Function ReplaceNonASCIIChars(ByVal html As String) As String
    Return Regex.Replace(html, "[^\u0000-\u007F]", " ")
End Function

2
Czy HTML zawiera jakieś meta informacje opisujące jego zestaw znaków?
Rowland Shaw

1
[Poprzedni komentarz usunięty] Krótka odpowiedź: nie.
Cᴏʀʏ

1
Dla mnie zadziałało: utf8_decode ()
ursuleacv

Odpowiedzi:


340

Gdzieś w tym bałaganie niełamliwe spacje z szablonu (ów) HTML są kodowane jako ISO-8859-1, dzięki czemu są wyświetlane nieprawidłowo jako znak „”

To byłoby kodowanie do UTF-8, a nie ISO-8859-1. Nieprzerwaną spacją jest bajt 0xA0 w ISO-8859-1; po zakodowaniu w UTF-8 będzie to 0xC2,0xA0, co jeśli (niepoprawnie) postrzegasz to jako ISO-8859-1, to znaczy " ". Obejmuje to ostatnią nbsp, której możesz nie zauważyć; jeśli tego bajtu nie ma, oznacza to, że coś innego zmieniło twój dokument i musimy dowiedzieć się więcej, aby dowiedzieć się, co.

Co to jest wyrażenie regularne, jak działa szablon? Wydaje się, że gdzieś zaangażowany byłby prawidłowy parser HTML, jeśli twoje  ciągi ((poprawnie) zostaną zamienione na znaki U + 00A0 NIENAKŁĄCE PRZESTRZEŃ. Jeśli tak, możesz po prostu przetworzyć szablon natywnie w DOM i poprosić go o serializację przy użyciu kodowania ASCII, aby zachować znaki spoza ASCII jako odwołania do znaków. To również powstrzymałoby cię przed ponownym przetwarzaniem wyrażeń regularnych na samym HTML, co jest zawsze bardzo podejrzaną działalnością.

Cóż, w każdym razie, na razie możesz dodać do dokumentu jeden z poniższych <head>i sprawdzić, czy to sprawia, że ​​wygląda on poprawnie w przeglądarce:

  • dla HTML4: <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  • dla HTML5: <meta charset="utf-8">

Jeśli to zrobisz, pozostały problem jest winą ActivePDF.


20
Nie poleciłbym <meta charset="utf-8">jeszcze. http-equivWersja jest nadal ważne w HTML5 i jest lepiej obsługiwane.
Bobin

8
Odpowiedzi, z których należy korzystać: <meta charset = 'utf-8'> vs <meta http-equiv = 'Content-Type' stwierdzają, że krótka wersja jest dobrze obsługiwana.
Richard Ayotte


Działa we wszystkich nowoczesnych przeglądarkach. Z pewnością nie działa we wszystkich przeglądarkach starszych i niszowych (np. Mobilnych) lub na wszystkich pająkach.
bobince

3
„Gdzieś w tym bałaganie” ... LOL! Miło otwarte! Dobra odpowiedź! +1
Odporność na projekt

24

Jeśli ktoś miał ten sam problem co ja, a zestaw znaków był już poprawny, po prostu zrób to:

  1. Skopiuj cały kod do pliku .html.
  2. Otwórz notatnik (lub dowolny podstawowy edytor tekstu) i wklej kod.
  3. Idź „Plik -> Zapisz jako”
  4. Wpisz swoją nazwę pliku „example.html” (Wybierz „Zapisz jako typ: Wszystkie pliki ( . )”)
  5. Wybierz Kodowanie jako UTF-8
  6. Naciśnij Zapisz, a teraz możesz usunąć stary plik .html, a kodowanie powinno zostać naprawione

2
Zrobiło to dla mnie. Teraz w Sublime mówi UTF-8 with BOMzamiast UTF-8. Aby zobaczyć to w wysublimowanym tekście, musisz show_encodingustawić truew Ustawienia - Użytkownik.
J86,

Miałem problem z wyświetlaniem  zamiast », amd Podczas korzystania z tego rozwiązania problem został rozwiązany, ale pojawia się ostrzeżenie php: Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at D:\Program Files\wamp\wamp\www\projects\kerala\kerala_public_html\edit\business_details.php:1) in D:\Program Files\wamp\wamp\www\projects\kerala\kerala_public_html\user\include\fg_membersite.php on line 152
SCC

To rozwiązanie działało dla mnie. Pracowałem w Notatniku ++, a kiedy zapisałem go w podstawowym MS Notatniku jako UTF-8, po otwarciu nowego pliku w Notatniku ++, kodowanie zostało ustawione na UTF-8-BOM (co nie jestem pewien, co to znaczy). W każdym razie wydaje mi się, że to był problem.
BoltKey

Dziękuję Ci! To załatwiło sprawę. Widzę w żądaniu / odpowiedzi, że plik (w moim przypadku ASPX) został zakodowany jako UTF-8. Notepad ++ miał także kodowany do UTF-8. Co do cholery, prawda? Ale twoje rozwiązanie załatwiło sprawę. Dla mnie była to hiszpańska fraza, która nie była poprawnie kodowana na stronie. Czytałem gdzie indziej, aby nie używać UTF-8 BOM dla hiszpańskiego, ale naprawiłem to dla mnie.
user3621633,

13

Problem: Nawet ja miałem do czynienia z problemem, w którym wysyłaliśmy „£” z pewnym łańcuchem w żądaniu POST do systemu CRM, ale kiedy robiliśmy wywołanie GET z CRM, zwracało „Â £” z pewną zawartością łańcucha. Przeanalizowaliśmy więc, że „£” zostało przekonwertowane na „Â £” .

Analiza: usterka, którą znaleźliśmy po przeprowadzeniu badań, polega na tym, że w wywołaniu POST ustawiliśmy HttpWebRequest ContentType jako „text / xml”, natomiast w wywołaniu GET było to „text / xml; charset: utf-8” .

Rozwiązanie: Więc jako część rozwiązania umieściliśmy charset: utf-8 w żądaniu POST i działa.


0

W moim przypadku miało to miejsce (z ostrożnością) w kodzie wygenerowanym przez Visual Studio przy użyciu własnego narzędzia do generowania kodu. Łatwo było rozwiązać:

Wybierz pojedyncze spacje () w dokumencie. Powinieneś być w stanie zobaczyć wiele pojedynczych spacji, które wyglądają inaczej niż inne pojedyncze spacje, nie są one zaznaczone. Wybierz te inne pojedyncze spacje - to one odpowiadają za niechciane postacie w przeglądarce. Przejdź do Znajdź i zamień na pojedynczą spację (). Gotowe.

PS: Łatwiej jest zobaczyć wszystkie podobne znaki, gdy umieścisz kursor na jednym lub jeśli wybierzesz go w VS2017 +; Mam nadzieję, że inne IDE mogą mieć podobne funkcje


-1

W moim przypadku zamiast nbsp dostawałem łaciński znak krzyżyka, nawet jeśli strona była poprawnie zakodowana w UTF-8. Nic z powyższego nie pomogło w rozwiązaniu problemu i próbowałem wszystkiego.

W końcu pomogła zmiana czcionki dla IE (z css specyficznym dla przeglądarki), użyłem Helvetica-Nue jako czcionki ciała zmieniającej się na Arial rozwiązał problem.


Przyczyną, dla której zmiana czcionki mogła pomóc, może być to, że jedna z czcionek nie zawierała danego znaku, więc zamiast tego zobaczyłeś pusty znak. Ale to nie rozwiązało problemu, tylko go zakryło.
Oliver Hausler

-2

Miałem ten sam problem. Najwyraźniej to po prostu dlatego, że PHP nie rozpoznaje utf-8.

Na początku odrywałem włosy, gdy znak „£” pojawiał się jako „Â £”, mimo że w DreamWeaver wyglądał dobrze. W końcu przypomniałem sobie, że miałem problemy z linkami w stosunku do pliku indeksu, kiedy strony, jeśli oglądane bezpośrednio, działałyby z pokazami slajdów, ale nie były używane z dołączeniem (ale to nie ma sensu. W każdym razie zastanawiałem się, czy to może być podobny problem, więc zamiast umieszczać na stronie, z którą miałem problemy, po prostu umieszczam go w pliku index.php - problem został naprawiony przez cały czas.



-2

Cóż, mam ten problem również na kilku stronach internetowych i wszystko, co muszę zrobić, to dostosować moduł pobierania treści dla wpisów HTML. przedtem więcej, usuwam je więcej, mam, więc po prostu zmień kod HTML lub funkcję parsowania strony i działało. Wynika to głównie z edytorów HTML w większości CMS-ów. sposób, w jaki przechowują parsowanie danych, spowodował ten problem (w moim przypadku). Niech to pomoże również w twoim przypadku

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.