最近有在做 stream 下载,并且边下载 stream 边处理功能、解析二进制的功能。最初参考了 flv.js 的 flv stream 下载处理功能,发现他并没有使用的 XMLHttpRequest 的 responseType = ‘arraybuffer’ 这个功能,而是使用的fetch api 里面的 body.getReader API。(fetch 支持一边下载二进制数据一边处理)

后来查询了资料发现, XMLHttpRequest 里不支持下载 stream 的同时边处理的 stream。如果你这么做了,你的 xhr.response 一直为null,直到stream完整下载。

  • XHR prevents to access the binary response (with arraybuffer response type) data before the request is complete.
  • XHR response is essentially one big buffer that keeps growing linearly as the response data comes in which means it can't get garbage collected.

https://stackoverflow.com/questions/30287813/receive-binary-data-in-web-browser-from-http-server-in-a-streaming-style

但是可以用另外一种方法绕过去。比如指定找个类型为 text。xhr 就不会下载完才会返回完整数据,而是可以做到边下载边获取数据,但是需要做编码转换

var xhr = new XMLHttpRequest();
var streamOffset = 0; xhr.overrideMimeType('text/plain; charset=x-user-defined');
xhr.open("GET", url, true);
xhr.send(); xhr.onreadystatechange = function () {
var textBuffer = xhr.responseText;
var arrayBuffer = textToArrayBuffer(textBuffer, streamOffset);
} function textToArrayBuffer(textBuffer, startOffset) {
var len = textBuffer.length - startOffset;
var arrayBuffer = new ArrayBuffer(len);
var ui8a = new Uint8Array(arrayBuffer, 0); for (var i = 0, j = startOffset; i < len; i++, j++){
ui8a[i] = (textBuffer.charCodeAt(j) & 0xff);
} return arrayBuffer;
}

上面的方法是在对webkit 内核浏览器做的兼容,但是其实在火狐浏览器和ie浏览器中有对这种场景的实现。

XMLHttpRequestResponseType

如下是常见的值:

"arraybuffer" ArrayBuffer
"blob" Blob
"document" Document
"json" JavaScript object, parsed from a JSON string returned by the server
"text" DOMString

自己的说明可以参考我之前写的文章:前端多媒体(2)—— xhr异步接收处理二进制数据

但是我阅读了一下 flv.js 对非weikit内核的流下载发现其实还有别的浏览器类型的实现。在IE和火狐浏览器可以做到边下载留边获取流边处理,而不用等到下载完以后才能处理流

  • moz-blob

    • Used by Firefox to allow retrieving partial Blob data from progress events. This lets your progress event handler start processing data while it's still beingreceived.
    • 在火狐浏览器你设置这个值,你可以在progress 事件里获取到 blob 数据
  • moz-chunked-text
    • Similar to "text", but is streaming. This means that the value in response is only available during dispatch of the "progress" event and only contains the data received since the last "progress" event.When response is accessed during a "progress" event it contains a string with the data. Otherwise it returns null.This mode currently only works in Firefox.
    • 在火狐浏览器你设置这个值,和 text 类型相似,但是可以在 response 里获取 text stream
  • moz-chunked-arraybuffer
    • Similar to "arraybuffer", but is streaming. This means that the value in response is only available during dispatch of the "progress" event and only contains the data received since the last "progress" event.When response is accessed during a "progress" event it contains a string with the data. Otherwise it returns null.This mode currently only works in Firefox.
    • 在火狐浏览器你设置这个值, 和 arraybuffer 类型相似,但是可以在 response 里获取 arraybuffer stream
  • ms-stream
    • Indicates that the response is part of a streaming download. It is supported only for download requests. This mode is available only in Internet Explorer.
    • 在 IE 浏览器里,可以实现 stream 下载

参考资料

ajax stream 一边下载二进制数据一边处理的更多相关文章

  1. 详细解读XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度

    本文主要参考:MDN 分析并操作 responseXML属性 如果你使用 XMLHttpRequest 来获得一个远程的 XML 文档的内容,responseXML 属性将会是一个由 XML 文档解析 ...

  2. 背水一战 Windows 10 (89) - 文件系统: 读写文本数据, 读写二进制数据, 读写流数据

    [源码下载] 背水一战 Windows 10 (89) - 文件系统: 读写文本数据, 读写二进制数据, 读写流数据 作者:webabcd 介绍背水一战 Windows 10 之 文件系统 读写文本数 ...

  3. HTML5新特性之文件和二进制数据的操作

    历史上,JavaScript无法处理二进制数据.如果一定要处理的话,只能使用charCodeAt()方法,一个个字节地从文字编码转成二进制数据,还有一种办法是将二进制数据转成Base64编码,再进行处 ...

  4. ajax发送请求下载字节流形式的excel文件

    背景 开发项目中导出功能,因为数据量有点大,所以导出可能需要时间有点长,所以想用ajax异步请求. 存在问题 利用传统的js和jquery提供的ajax相关获取响应的方式是无法实现excel文件下载的 ...

  5. 数据库中用varbinary存储二进制数据

    问题描述:将图片.二进制文件内容等数据存储在数据库中,并能从数据库中取出还原为图片或文件,数据库存储二进制数据用varbinary字段. 分析:由于之前数据库中没有用过varbinary存储数据,首先 ...

  6. 本地主机作服务器解决AJAX跨域请求访问数据的方法

    近几天学到ajax,想测试一下ajax样例,由于之前在阿里租用的服务器过期了,于是想着让本地主机既做服务器又做客户端,只是简单地测试,应该还行. 于是,下载了xampp,下载网址http://www. ...

  7. 巧用ajax请求服务器加载数据列表时提示loading

    我们利用weui.js中的weui.loading为效果,ajax的beforeSend与complete方法,做一个加载数据时会有几秒的 loading... 要在页面需要加载的JS文件: < ...

  8. angular2/angular4 如何通过$http的post方法请求下载二进制的Excel文件

    时间有限,废话就不多说了,直接上干货! 下面给大家介绍一下我遇到的一个坑,如果你也遇到了,那恭喜你,你一定能找到答案:angular2/angular4 如何通过$http的post方法请求下载二进制 ...

  9. Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)

    目录 SignalR系列目录(注意,是ASP.NET的目录.不是Core的) 前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于Signal ...

随机推荐

  1. 为什么使用JSP?

    JSP程序与CGI程序有着相似的功能,但和CGI程序相比,JSP程序有如下优势: 性能更加优越,因为JSP可以直接在HTML网页中动态嵌入元素而不需要单独引用CGI文件. 服务器调用的是已经编译好的J ...

  2. 【Atheros】Ath9k速率调整算法源码走读

    上一篇文章介绍了驱动中minstrel_ht速率调整算法,atheros中提供了可选的的两种速率调整算法,分别是ath9k和minstrel,这两个算法分别位于: drivers\net\wirele ...

  3. <button>标签也能提交表单问题

    如何避免<button>标签也能提交表单的问题: 只需加上一个属性:type='button'即可:如<button type="button"> < ...

  4. 使用Swoole加速Laravel(正式环境中)

    1 Laravel的速度瓶颈在哪? 1.1 已有的一些优化方法 1.1.1 laravel官方提供了一些优化laravel的优化方法 php artisan optimize php artisan ...

  5. urllib.urlencode() 无法encode中文, UnicodeEncodeError

    urllib.urlencode() 无法encode中文, UnicodeEncodeError, 具体错误内容如下:File "/System/Library/Frameworks/Py ...

  6. Linux 服务器上建立用户并分配权限

    查看用户 whoami #要查看当前登录用户的用户名 who am i #表示打开当前伪终端的用户的用户名 who mom likes who 命令其它常用参数 参数 说明 -a 打印能打印的全部 - ...

  7. 【BZOJ4016】[FJOI2014]最短路径树问题 最短路径树+点分治

    [BZOJ4016][FJOI2014]最短路径树问题 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径 ...

  8. Count(二维树状数组)

    [bzoj1452][JSOI2009]Count Description Input Output Sample Input Sample Output 12   HINT 题解:对于每一个颜色建一 ...

  9. xlrd python excel

     xlrd python excel

  10. mydql练习答案

    .查询“生物”课程比“物理”课程成绩高的所有学生的学号: 思路: 获取所有有生物课程的人(学号,成绩) - 临时表 获取所有有物理课程的人(学号,成绩) - 临时表 根据[学号]连接两个临时表: 学号 ...