最近有在做 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. 搜索maven的库中某个支持库的的最新版本

    首先放网址(建议挂个vpn): maven库中心:http://search.maven.org/ jcenter库中心:https://bintray.com/bintray/jcenter 接下来 ...

  2. 开发app应用的开源项目推荐

    app检测内存泄漏 请看这里:LeakCanary Android 和 Java 内存泄露检测 app应用想要控制状态栏 StatusBarUtil :https://github.com/laobi ...

  3. Warning: (3719, “‘utf8’ is currently an alias for the character set UTF8MB3, which will be replaced by UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.”)

    [1]本地版本 Mysql 8.0.12 创建表SQL: DROP TABLE IF EXISTS students; CREATE TABLE `students` ( `sId` ) UNSIGN ...

  4. mysql海量数据条件删除

    1. 问题描述:现在存在两个表,具体表结构及记录数如下所示: mysql> desc user_mapping; +------------+------------------+------+ ...

  5. Razor里写函数

    asp.net mvc的视图里使用Razor来书写服务器代码,人尽皆知.可以常常见到里面写上for循环语句,输出一大堆东东,牛逼得很. 可是,如果循环语句还不能满足我们的要求,需要定义一个函数来调用, ...

  6. CAFFE学习笔记(一)Caffe_Example之训练mnist

    0.参考文献 [1]caffe官网<Training LeNet on MNIST with Caffe>; [2]薛开宇<读书笔记4学习搭建自己的网络MNIST在caffe上进行训 ...

  7. 在jsp中嵌入javascript代码执行对html的影响方式

    1 javascript的作用范围 javascript操作的是html dom树. 它可以用来直接写入html标签:修改html的内容:响应事件:修改html中的图像:修改html的样式等等. 2 ...

  8. HealthKit详解

    1. 导入HealthKit框架 #import <HealthKit/HealthKit.h> 2. 判断设备是否支持HealthKit HealthKit是iOS8加入的API Hea ...

  9. html5plus (H5 WebApp)

    是什么? 它是增强版的手机浏览器引擎, 让HTML5达到原生水平, 它提供WebApp的规范. 它结合MUI(前端框架) + HBuilder(开发工具) 即可迅速实现开发一个app. 快速起步? 1 ...

  10. 在函数中如何获取 线程对象、线程唯一ID

    threading.current_thread() threading.current_thread().ident