2017-10-15 4 views
2

Ich mag mit xmlHttpRequest ein Dokument aus dem Internet holen. Allerdings ist der betreffende Text nicht utf8 (in diesem Fall ist es Windows-1251, aber im generischen Fall würde ich das nicht sicher wissen).Fetching Nicht-UTF-8-Daten mit XMLHttpRequest

Allerdings, wenn ich responseType="text" verwende es behandelt es, als ob die Zeichenfolge utf8 ist, ignoriert den Zeichensatz in der Content-Type (was zu einem fiesen Durcheinander).

Wenn ich ‚Blob‘ hat (wahrscheinlich die nächste Sache, was ich will), kann ich konvertiere dann, dass auf eine DOMString die Codierung berücksichtigt?

+1

'Ignorieren der charset im Content-Baumuster zur Sind Sie sicher, liest der Server korrekt die Datei als Windows-1251 dient sie als solche und antwortet mit dem richtigen Inhaltstyp? Wenn einer dieser drei Fehler auftritt, könnten Sie mit einer Buchstabensuppe fertig werden, bevor sogar ein einzelnes Byte im Browser eintraf. – Thomas

+0

'Konvertieren Sie das zu einem DomString unter Berücksichtigung der Codierung 'Ich bin mir nicht bewusst, eine API/lib für diesen, aber im schlimmsten Fall können Sie jedes Byte auf die richtige char zuordnen. – Thomas

Antwort

2

Ich fand tatsächlich eine API, die das tut, was ich will, von hier:

https://developers.google.com/web/updates/2014/08/Easier-ArrayBuffer-String-conversion-with-the-Encoding-API

Grundsätzlich verwenden responseType="arraybuffer", die Codierung von den zurückgegebenen Header holen, und DataView und TextDecoder verwenden. Es macht genau das, was benötigt wird.

const xhr = new XMLHttpRequest(); 
 
xhr.responseType = "arraybuffer"; 
 
xhr.onload = function() { 
 
    const contenttype = xhr.getResponseHeader("content-type"); 
 
    const charset = contenttype.substring(contenttype.indexOf("charset=") + 8); 
 
    const dataView = new DataView(xhr.response); 
 
    const decoder = new TextDecoder(charset); 
 
    console.log(decoder.decode(dataView)); 
 
} 
 
xhr.open("GET", "https://people.w3.org/mike/tests/windows-1251/test.txt"); 
 
xhr.send(null);

fetch("https://people.w3.org/mike/tests/windows-1251/test.txt") 
 
    .then(response => { 
 
    const contenttype = response.headers.get("content-type"); 
 
    const charset = contenttype.substring(contenttype.indexOf("charset=") + 8); 
 
    response.arrayBuffer() 
 
     .then(ab => { 
 
     const dataView = new DataView(ab); 
 
     const decoder = new TextDecoder(charset); 
 
     console.log(decoder.decode(dataView)); 
 
     }) 
 
    })

1

Wenn ich 'Blob' (wahrscheinlich die nächste Sache, was ich will), könnte ich das dann zu einem DomString unter Berücksichtigung der Codierung konvertieren?

https://medium.com/programmers-developers/convert-blob-to-string-in-javascript-944c15ad7d52 beschreibt einen allgemeinen Ansatz, den Sie verwenden können. Anzuwenden, die für den Fall ein entferntes Dokument zu holen:

So:

const reader = new FileReader() 
 
reader.addEventListener("loadend", function() { 
 
    console.log(reader.result) 
 
}) 
 
fetch("https://people.w3.org/mike/tests/windows-1251/test.txt") 
 
    .then(response => response.blob()) 
 
    .then(blob => reader.readAsText(blob, "windows-1251"))

Oder wenn Sie stattdessen wirklich wollen, XHR verwenden:

const reader = new FileReader() 
 
reader.addEventListener("loadend", function() { 
 
    console.log(reader.result) 
 
}) 
 
const xhr = new XMLHttpRequest() 
 
xhr.responseType = "blob" 
 
xhr.onload = function() { 
 
    reader.readAsText(xhr.response, "windows-1251") 
 
} 
 
xhr.open("GET", "https://people.w3.org/mike/tests/windows-1251/test.txt", true) 
 
xhr.send(null)

Wenn ich jedoch responseType="text" verwenden sie es behandelt, als ob die Zeichenfolge utf8 ist, ignoriert die charset in der content-type

Ja. Das ist, was ist required by the Fetch spec (was für das ist, was die XHR-Spezifikation beruht auf zu):

Objekte der Umsetzung des Body mixin auch ein zugehöriges Paketdaten-Algorithmus haben, da Bytes, ein Typ und ein mime schaltet auf Typ und führt die dazugehörigen Schritte:
...
Text
Rückkehr der Ergebnis UTF-8 decode auf Bytes läuft.

+0

Ich habe diese Notiz in der Abrufspezifikation verpasst. Vielen Dank. Der Grund für die Verwendung von xmlhttprequest ist herauszufinden, was die Codierung ist. –