15

我有一个需要从中下载文件的设备。在某些情况下,该文件可能包含不正确的content-encoding. 特别是,当它没有被 gzip 压缩或以任何方式压缩时,它可能具有“gzip”的内容编码。

因此,当文件被 gzip 压缩时,使用基本的 ajax GET 获取内容很简单:

$.ajax({
    url: 'http://' + IP + '/test.txt',
    type: 'GET'
})
.done(function(data) {
    alert(data);
});

但是,正如您所料,当内容编码错误时,这会失败。

需要明确的是,我不是在寻找解决方案来绕过ERR_CONTENT_DECODING_FAILED浏览器中的给定网址。例如,我希望能够将 csv 加载到 javascript 中的字符串中以进行进一步解析。

我可以获取文件,并强制它跳过尝试解码,或覆盖响应的内容编码,或类似的吗?

4

2 回答 2

7

根据 WHATWG 的XHR 规范,这根本不可能通过客户端 JavaScript 完成,该规范利用WHATWG Fetch Standard中的fetch操作。

客户端脚本只能读取浏览器环境提供的响应对象。Fetch Standard 定义了浏览器环境必须如何在fetch操作的步骤 2 中构建响应对象的body属性(特别注意子步骤 2 到 4):

  1. 每当传输一个或多个字节时,让bytes为传输的字节并运行以下子子步骤:

    1. 增加响应的正文以字节的长度传输。

    2. 编码Content-Encoding成为响应头列表中解析的结果。

    3. 字节设置为处理给定编码字节的内容编码的结果。

    4. 将字节推送到响应的正文。

处理内容编码的动作是:

处理给定编码字节的内容编码,请运行以下子步骤:

  1. 如果不支持编码,则返回bytes

  2. 返回使用给定编码解码字节的结果,如 HTTP 中所述。

从这个定义中,我们可以看到响应对象永远不会在其body属性中公开编码字节。在将字节添加到正文之前,必须先对它们进行解码。客户端脚本永远无法访问规范所称的“传输字节”(即通过线路发送的实际编码字节)。

解码仅由Content-Encoding标头确定。客户端 JavaScript 没有机制可以操纵响应对象的响应标头,因此Content-Encoding必须是服务器最初发送的任何内容。

您的服务器正在执行的操作是错误的。您唯一的选择是:

  1. 修复服务器的行为。

  2. 通过代理运行 HTTP 响应,该代理会在Content-Encoding响应标头到达您的客户端之前对其进行修复。

于 2015-04-21T20:34:29.387 回答
2

在基于浏览器的现代环境中,由于 HttpRequest 的同源策略,您无法更改 Accept-Encoding:

链接到谷歌的解释

对于您的脑残设备,最好的解决方法是使用服务器端代理来获取内容并忽略不正确的编码,然后使用一组合理的标头返回结果。

于 2015-04-21T19:45:33.500 回答