XMLHttpRequest 206 部分内容

17
我想在JavaScript中使用XMLHttpRequest对象发出部分内容请求。我正在从服务器加载一个大的二进制文件,并希望将其从服务器流式处理,类似于处理HTML5视频。
我可以使用setRequestHeader设置Range头。Chrome中的网络检查器显示,Range头已成功设置。但是,Accept-Encoding标头被设置为"gzip、deflate",而根据W3C标准,Chrome不允许我设置该标头。
是否有任何方法只使用JavaScript强制服务器以206部分内容响应XMLHttpRequest对象?

1
你也负责编写/维护服务器端代码吗?还是只做客户端脚本编写? - Kijewski
1
我更喜欢保持客户端,尽管我可以访问服务器端。我正在编写一个生成静态页面的东西,可以上传到其他主机,所以我宁愿不要去处理服务器端... - jamesshuang
2个回答

18

这个范围请求对我来说很好用:http://jsfiddle.net/QFdU4/

var xhr = new XMLHttpRequest;

xhr.onreadystatechange = function () {
  if (xhr.readyState != 4) {
    return;
  }
  alert(xhr.status);
};

xhr.open('GET', 'http://fiddle.jshell.net/img/logo.png', true);
xhr.setRequestHeader('Range', 'bytes=100-200'); // the bytes (incl.) you request
xhr.send(null);

你必须确保服务器允许范围请求,你可以使用curl进行测试:

$ curl -v -r 100-200 http://example.com/movie.mkv > /dev/null

2
嗯,这很奇怪。我也向一个nginx服务器发出请求。使用-r命令,Curl可以正常工作。但是,当我在浏览器中尝试运行完全相同的代码时,我只能得到一个200响应,对于这个大的八位流(40 mb)。有什么线索可以解释这种情况吗? - jamesshuang
1
你的Fiddle响应是206。将代码复制并在我的服务器上运行,会得到200。有哪些服务器变量可能会影响这个结果? - jamesshuang
1
抱歉,我只了解Apache。我做了一些谷歌搜索,但没有找到任何信息。也许你的问题最好在http://serverfault.com/上问问? - Kijewski

12

我想我已经找到了206请求无法工作的原因。启用gzip压缩后,如果传出的数据可以进行gzip压缩,则会忽略范围头。

我正在请求的文件是一个大的二进制文件,nginx将其解释为具有mimetype应用程序/八位字节流。这是一个被gzip压缩的mimetype之一。如果我将文件重命名为.png文件类型,那么image/png mimetype不会被压缩,因此范围请求将正常工作。

这也是为什么使用curl设置Accept-Encoding header 为identity也能让范围请求正常工作的原因。但是,我不能从XHR更改该标头。

解决方案:更改服务器上的mimetype表!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接