Wie kann ich dem Browser die Zeichenkodierung einer HTML-Website unabhängig vom Header des Server-Inhaltstyps mitteilen?

9

Ich habe eine HTML-Seite, die korrekt (die Codierung des physischen Datenträgers stimmt damit überein) den Inhaltstyp anzeigt :

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content=
    "text/html; charset=utf-8">
    <title> ...

Das Öffnen der Datei von der Festplatte im Browser (Google Chrome, Firefox) funktioniert einwandfrei.

Der Webserver fordert es über HTTP an und sendet einen anderen Content-Type-Header:

$ curl -I http://example.com/file.html
HTTP/1.1 200 OK
Date: Fri, 19 Oct 2012 10:57:13 GMT
...
Content-Type: text/html; charset=ISO-8859-1

(siehe letzte Zeile). Der Browser verwendet dann ISO-8859-1, um anzuzeigen, was ein unerwünschtes Ergebnis ist.

Gibt es eine übliche Möglichkeit, die an den Browser gesendeten Server-Header aus dem HTML-Dokument heraus zu überschreiben?

hakre
quelle

Antworten:

6

"Gibt es eine übliche Möglichkeit, die an den Browser gesendeten Server-Header aus dem HTML-Dokument heraus zu überschreiben?"

AFAIK nein, du tust was du schon kannst. Der über Header definierte Zeichensatz übertrifft Ihre Definition im META-Tag.

Wenn Sie Zugriff auf den Server haben, z. B. Apache, wird dieser durch diese Anweisung konfiguriert (siehe Kommentarzeilen):

# Read the documentation before enabling AddDefaultCharset.
# In general, it is only a good idea if you know that all your files
# have this encoding. It will override any encoding given in the files
# in meta http-equiv or xml encoding tags.

#AddDefaultCharset UTF-8

[Aktualisieren]

Zum zweiten Kommentar von w3d hier finden Sie einige Möglichkeiten, den Zeichensatz über htaccess-Direktiven für den Apache-Server zu ändern .

anfänglich
quelle
2
+1 HTTP-Header überschreiben HTML-Meta-Tags. Wenn @hakre Zugriff auf die Serverseite hat, können sie auch den Content-Type-Header pro Seite überschreiben.
MrWhite
3
Richtig, hier ist die normative Referenz, die angibt, dass HTTP-Header Meta-Tags übertrumpfen
Jukka K. Korpela
Danke für die Antwort. @Korpela: Ja, das hatte ich mit den HTML-Spezifikationen im Speicher. Es ist genau umgekehrt, wie ich es brauche :(.
hakre
In Bezug auf .htaccess (sorry, dies sollte möglicherweise stattdessen eine neue Frage sein) ist es möglich, die auch ;charset=...aus dem http-Header zu entfernen . Die Seite funktioniert sehr gut mit Content-Type: text/html, verschiedene Dateien haben unterschiedliche Codierungen auf dem Server. (Ich fürchte, das ist auch nicht möglich, weil ich glaube, ich habe das vor einigen Wochen gesucht, aber das Ergebnis war nicht ganz endgültig). Nur für den Fall, dass Sie direkt vor Ihnen Licht ins Dunkel bringen können.
hakre
@hakre Wenn die ForceType-Direktive von Apache für Sie funktioniert, platzieren Sie sie in einem <Files> -Container und benennen Sie Dateien oder bestimmte Verzeichnisse einzeln. Lassen Sie einfach den Teil "; charset =" nach dem MIME-Typ, dies sollte es tun.
Anfang
3

Sie sollten so etwas in Ihrem Stammverzeichnis .htaccess festlegen

<FilesMatch "\.(htm|html|xhtml|xml|php)$">
    AddDefaultCharset utf-8
</FilesMatch>
Patome
quelle
3

Nein, das ist im HTML nicht möglich. Der Antwortheader des Servers hat Vorrang vor dem Meta-Tag des Dokuments. Wie in 5.2.2 angegeben. Angeben der Zeichenkodierung - HTML 4.01 Spezifikation :

Zusammenfassend müssen konforme Benutzeragenten bei der Bestimmung der Zeichenkodierung eines Dokuments (von der höchsten zur niedrigsten Priorität) die folgenden Prioritäten beachten:

  1. Ein HTTP-Parameter "Zeichensatz" in einem Feld "Inhaltstyp".
  2. Eine META-Deklaration mit "http-equiv" auf "Content-Type" und einem Wert für "charset".
  3. Das Zeichensatzattribut, das für ein Element festgelegt wurde, das eine externe Ressource bezeichnet.

Dies erfordert also eine Konfiguration auf der Serverseite. Im weiteren Verlauf des Kapitels:

Benutzeragenten bieten möglicherweise einen Mechanismus, mit dem Benutzer falsche "Zeichensatz" -Informationen überschreiben können. Wenn ein Benutzeragent einen solchen Mechanismus anbietet, sollte er ihn nur zum Durchsuchen und nicht zum Bearbeiten anbieten, um die Erstellung von Webseiten zu vermeiden, die mit einem falschen "Zeichensatz" -Parameter gekennzeichnet sind.

In meinem Fall enthält der Content-Type- Header des Servers den richtigen MIME-Typ, aber den falschen Zeichensatz .

Wie sich herausstellte, hatte meine Apache-httpd-Konfiguration die Option AddDefaultCharsetzum Hinzufügen des ; charset=ISO-8859-1Teils aktiviert . Platzieren Sie .htaccessdie folgende Zeile im Stammverzeichnis der Website :

AddDefaultCharset Off

Die Zeichensatzinformationen wurden entfernt:

$ curl -I http://example.com/file.html
HTTP/1.1 200 OK
Date: Fri, 19 Oct 2012 15:07:52 GMT
...
Content-Type: text/html

(siehe letzte Zeile, kein ; charset=...Teil). Dies in Kombination mit dem HTML-Meta-Tag löst aus, dass die Browser-Heuristik den Zeichensatz vom Meta-Tag übernimmt . Die Website ist ordnungsgemäß dekodiert.

Getestet mit:

  • Google Chrome v. 22.0.1229.94
  • Firefox v. 16.0.1
  • Lynx Version 2.8.7rel.1 (05. Juli 2009)

Diese drei Browser hatten Probleme mit der ursprünglichen Konfiguration und funktionieren jetzt (alle unter Fedora 17).

  • Opera 12.02
  • Internet Explorer 6 (Win XP SP3)

Hatte das Problem überhaupt nicht. Beide bevorzugten UTF-8 aus dem Meta-Tag gegenüber der ISO-8859-1- Einstellung vom Server.

  • Netscape 2.01 Gold

Unterstützt UTF-8 nicht und wählt daher immer Western (Latin1), unabhängig von der Servereinstellung und dem Meta-Tag.

hakre
quelle
1

Zusätzlich zu dem, was hier gesagt wurde, würde ich versuchen, auf allen Seiten den gleichen Zeichensatz zu verwenden - vorzugsweise UTF-8(aber wenn fast alles vorhanden ist iso-8859-1, verwenden Sie diesen).

Um den Zeichensatz einer Datei schnell zu überprüfen, können Sie Folgendes versuchen:

file --mime-type --mime-encoding {filename}

Um den Zeichensatz aller Dateien in der Baumstruktur zu überprüfen, können Sie Folgendes versuchen:

find . -type f -exec file --mime-type --mime-encoding '{}' \;

oder (den fileBefehl nur einmal aufrufen ):

find . -type f -print | file --mime-type --mime-encoding -f-

Um eine Zusammenfassung zu erhalten, verwenden Sie die -bOption zum fileBefehl (um die Dateinamen wegzulassen) und leiten Sie das Ergebnis an weiter sort | uniq -c.

Tobias
quelle