Da ich nirgendwo verlässliche Informationen über die Behandlung von Zeichensätzen im Zusammenhang mit XMLHttpRequests* finden konnte, habe ich selbst einige Versuche angestellt und bin zu folgenden Erkenntnissen gelangt:

(Die beiden zentralen Konzepte sind fett markiert.)

  • Texte in per ‹script src="…"› eingebundenen Javascript-Dateien werden mit dem Zeichensatz der HTML-Datei interpretiert, in der sie eingebunden sind, außer es wird mit dem Attribut charset explizit ein anderer Zeichensatz angegeben.
    Dies ist insofern sinnvoll, als ein solches Script ja so betrachtet wird, als ob es direkt in die HTML-Datei geschrieben wäre.
  • Texte, die per AJAX geholt werden, werden mit dem Zeichensatz interpretiert, der bei der Übertragung (also dem HTTP-Request) übermittelt wurde. (Unabhäng vom Zeichensatz der Javascript-Datei, die die Übertragung initiiert hat.)
    Auch dies ist eigentlich intuitiv verständlich, wenn man die Zeichenkodierung als eine Eigenschaft des Übertragungskanals versteht.
  • Wird bei der Antwort auf den XMLHttpRequest kein Zeichensatz angegeben, interpretiert zumindest Firefox sie als UTF-8.
  • Wird weder bei der Seite noch bei einer eingebundenen JS-Datei eine Zeichenkodierung angegeben, werden darin enthaltene Zeichen korrekterweise als ISO-8859–1 interpretiert.
  • Obige Aussagen gelten uneingeschränkt auch für JSON, somit ist die JSON‑Übertragung nicht bit-transparent sondern zeichentransparent. Zeichen können mit Hilfe der \uxxxx-Notation auch direkt als Unicode-Code-Points angegeben werden.
  • Firebug zeigt immer die fertig dekodierten Zeichen an. String.charCodeAt() gibt immer den Unicode-Code-Point an, egal wie das Zeichen gekommen ist. Data URIs wandeln die Zeichen wieder unter Annahme eines angegeben Zeichensatzes zurück in Zeichencodes.

Hier noch der Testcase zum Download.

 

    * Warum ist XML eigentlich groß- und Http kleingeschrieben?