【问题标题】:Fetching non-utf8 data with XMLHttpRequest使用 XMLHttpRequest 获取非 utf8 数据
【发布时间】:2017-10-15 08:33:51
【问题描述】:

我想使用xmlHttpRequest 从网上获取一个文档。但是,有问题的文本不是 utf8(在这种情况下是 windows-1251,但在一般情况下,我不确定)。

但是,如果我使用 responseType="text",它会将其视为字符串是 utf8,忽略内容类型中的字符集(导致一团糟)。

如果我使用了“blob”(可能是我想要的最接近的东西),我是否可以在考虑编码的情况下将其转换为 DomString?

【问题讨论】:

  • ignoring the charset in the content-type 你确定,服务器正确读取文件为 windows-1251,服务它,并以正确的内容类型响应?如果这三个中的任何一个失败了,你可能会在一个字节到达浏览器之前得到字母汤。
  • convert that to a DomString taking into account the encoding 我不知道有一个 api/lib,但最坏的情况是,您可以将每个字节映射到正确的字符。

标签: javascript utf-8 xmlhttprequest


【解决方案1】:

实际上,我从这里找到了一个可以满足我需求的 API:

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

基本上,使用responseType="arraybuffer",从返回的标头中选择编码,然后使用DataViewTextDecoder。它完全符合要求。

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));
      })
  })

【讨论】:

    【解决方案2】:

    如果我使用了“blob”(可能是我想要的最接近的东西),我是否可以在考虑编码的情况下将其转换为 DomString?

    https://medium.com/programmers-developers/convert-blob-to-string-in-javascript-944c15ad7d52 概述了您可以使用的一般方法。将其应用于获取远程文档的情况:

    像这样:

    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"))

    或者如果你真的想使用 XHR:

    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)

    但是,如果我使用responseType="text",它会将其视为字符串为 utf8,而忽略内容类型中的字符集

    是的。这就是required by the Fetch spec(这也是 XHR 规范所依赖的):

    实现Body mixin 的对象也有一个相关的包数据算法,给定 bytes,一个 type 和一个 mimeType,开启输入,然后运行相关步骤:

    文字
    返回在 bytes 上运行 UTF-8 decode 的结果。

    【讨论】:

    • 我错过了 fetch 规范中的注释。谢谢。使用 xmlhttprequest 的原因是为了找出编码是什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 2015-08-28
    • 2016-05-30
    • 2012-01-29
    • 1970-01-01
    • 2018-08-28
    相关资源
    最近更新 更多