最近有在做 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. C语言基础知识【数据类型】

    C 数据类型1.在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统.变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式.2.C 中的类型可分为以下几种:序号    类 ...

  2. 一个手动备份MySQL数据库的脚本

    #!/bin/bash username=root hostname=localhost password=root mysql -u$username -h$hostname -p$password ...

  3. StarUML破解教程

    StarUML破解教程 StarUML官方下载地址:http://staruml.io/download StarUML是一个非常好用的画UML图的工具,但是它是收费软件,以下是破解方法: 1.使用E ...

  4. 数据预处理及sklearn方法实现

    1.标准化(中心化) 在许多机器学习执行前,需要对数据集进行标准化处理.因为很对算法假设数据的特征服从标准正态分布.所以如果不对数据标准化,那么算法的效果会很差. 例如,在学习算法的目标函数,都假设数 ...

  5. SQLServer2008 统计表占用空间

    1.查看一张表占用的空间大小 EXEC sp_spaceused '表' 1.查看一个数据库中所有表占用空间大小 EXEC sp_MSforeachtable 'sp_spaceused " ...

  6. Java水印图片处理

    今天需要用Java程序给图片加水印,于是在网上找到了一段代码,感觉很好,于是记录了下来,原来的网址给忘了: import java.awt.AlphaComposite; import java.aw ...

  7. JavaScript-Confirm用法

    function checkMobileBind() {    if(confirm('您尚未绑定手机,是否前往绑定?'))    {        window.location='http://m ...

  8. 8.Django模型类例子

    这里定义4个模型 作者:一个作者有姓名 作者详情:包括性别,email,出生日期, 出版商:名称,地址,城市,省,国家,网站 书籍:名称,日期 分析: 作者详情和作者一对一的关系 一本书可以有多个作者 ...

  9. Jquery事件绑定的4中方式对比

    bind()向匹配元素添加一个或多个事件处理器. 使用方式 $(selector).bind(event,data,function) event:必需项:添加到元素的一个或多个事件,例如 click ...

  10. linux nginx完全卸载

        Nginx虽然好用,但是一旦关键配置文件被修改,想要卸载重装却是相当困难.本人因为采用apt-get方式安装后又源码安装了Nginx,结果出现冲 突,卸载不了,安装不上,很是蛋疼.主要的问题还 ...