ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践
本文转自一位高人的博客:情郎 Blog
写在前面 :从提出需求到完美的解决问题,实现过程是曲折的。
需求:在前(web client)后(Restful Service)端完全解耦的模式框架下,webclient需要请求 Service 返回的图片文件(二进制流),并在client端显示。
第一步思考:拿到此需求, 基于程序员的狂妄心里,思考到显示图片而已,jquery ajax直接get请求 将返回data 赋值给img标签的src属性即可嘛,so easy~
不知天高地后的小子开始码代码,经过几分钟给出了以下的代码,并自信满满的准备测试。
$.ajax({method: "GET",url: serverUrlBase + "/server/images/" + mapid + "/files/png",//跨域,请求会返回流文件 png图片beforeSend: function (xhr) {xhr.setRequestHeader("client_type", "DESKTOP_WEB");xhr.setRequestHeader("desktop_web_access_key", _desktop_web_access_key);},success: function (data) {$("#remoteimg").attr("url", data);}
});
在visual studio 中选中文件 在浏览器中查看。
这是个什么~!!!!!!!!!!!!!!! 不符合期望啊~~~ !!!!!!!!!
第二步思考:后端那小子给的API肯定有问题。先用工具测试看看。
打开chorme ,打开装好的postman组件,输入请求地址,点击SEND。等待两秒钟一副超大的图片文件显示出来了~~
第三步思考:后端那小子的接口是正常的。 问题在我自己身上(表情渐渐严肃。) 把请求到的数据 console.log(data) 一下。
经过几分钟卡顿,我勒个去,浏览器怎么卡死了。耐心等了一会 数据打印出来了:
这是什么乖乖,我滴孩嘞(正统 淮南话)。
第四步思考:怎么是这样的数据。Postman 中返回的是图片啊 我的怎么这样,对了 看看postman 返回的是什么数据。
在postman中选中图片 -》右键-》检查 如下图所示:
第五步思考:为什么我的数据与postman数据不同。为何是乱码咧? 不对,ajax返回的数据是什么?难道编码被改了?难道不支持二进制流?
一边想着 一边打开jquery 官网(抱怨一下 jquery官网真心慢,w3school真心肤浅) 查找ajax datatype数据类型
发现竟然没有二进制数据选项,那是不是返回的数据被默认以文本形式返回了。
抱怨:jquery做了这么久了 一个ajax方法还停留在几年前的xmlhttprequest 1的版本中,惊人的不支持流文件!!!
我这还怎么大肆推行我的前后台完全隔离思想~~。算了不抱怨了,果然是不能靠别人,只能自己写了。
楼主依稀记得 xmlhttprequest 2 标准中支持流文件的,并且应该使用 xhr.response作为返回 而不是responseText。 那么开始写到:
var url = serverUrlBase + "/server/images/" + mapid + "/files/png";'
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);//get请求,请求地址,是否异步
xhr.setRequestHeader("client_type", "DESKTOP_WEB");
xhr.setRequestHeader("desktop_web_access_key", _desktop_web_access_key);
xhr.onload = function() {if (this.status == 200) {var data = this.response;//TODO..........如何接收数据呢。}
}
xhr.send();
第六步思考: 这样应该可行,但是怎么处理请求的数据呢? ???? 这个问题。 对了 html5新特性里面是不是 提到一个 Blob对象来着。试试看。
通过查阅相关blob资料,查阅 4.6.9 The response attribute 得知 返回类型应该使用
在请求成功的地方 添加以下代码:
var blob=new Blob();
blob=this.response;
既然二进制数据拿到了,那么要把它放在一个 html标签中,并且应该是img标签 那么:代码应该是
var img = document.createElement("img");
img.src = window.URL.createObjectURL(blob); //有问题,将blob加载到img中 由于blob太大 会有性能影响 应该怎么在加载之后 如何释放呢:
img.onload = function(e) {window.URL.revokeObjectURL(img.src);//释放。
};
然后 将img 放到一个div容器中就可以啦。
$(“#imgcontainer”).html(img); 是的请求处理就应该是这样。
那么我们最终的代码如下:
var url = serverUrlBase + "/server/images/" + mapid + "/files/png";
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = "blob";
xhr.setRequestHeader("client_type", "DESKTOP_WEB");
xhr.setRequestHeader("desktop_web_access_key", _desktop_web_access_key);
xhr.onload = function() {if (this.status == 200) {var blob = this.response;var img = document.createElement("img");img.onload = function(e) {window.URL.revokeObjectURL(img.src); };img.src = window.URL.createObjectURL(blob);$("#imgcontainer").html(img); }
}
xhr.send();
结语:这样楼主解决了 加载二进制流的问题。 结合 上一篇提到的 ajax跨域请求,对于前后端完全分离理念的实现又更近了一步。当然面对安全还是有许多要考虑的问题。
在此过程中,也让搂着领悟到一点:高阶的封装(ajax)固然好,然而对一些特殊的请求无法处理(请求流文件),因此还需掌握底层的原理,才能面对苛刻的需求。
总结代码:
var xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.responseType = "blob";
xhr.onload = function() {if (this.status == 200) {var blob = this.response;var img = document.createElement("img");img.onload = function(e) {window.URL.revokeObjectURL(img.src); };img.src = window.URL.createObjectURL(blob);$("#imgcontainer").html(img);}
}
xhr.send();
参考资料:
http://api.jquery.com/jQuery.ajax/ jquery ajax api
https://xhr.spec.whatwg.org/ xmlhttprequest 规范
https://xhr.spec.whatwg.org/#the-responsetype-attribute responsetype返回类型支持
http://www.zhangxinxu.com/wordpress/2013/10/understand-domstring-document-formdata-blob-file-arraybuffer/ xmlhttprequest 相关学习。
http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html xmlhttprequest 使用指南
本文转自一位高人的博客:情郎 Blog
ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践相关推荐
- Nginx增加m3u8流视频文件功能模块 推流和拉流
Nginx增加m3u8流视频文件功能模块 推流和拉流 FastDFS分布式文件系统安装和配置_亲测成功 ./configure --prefix=/u06/data/apps/nginx-rtmp \ ...
- c 语言解析png图片文件信息,利用C/C++二进制读写png文件的方法示例
前言 二进制文件不是以ASCII代码存放数据的,它将内存中数据存储形式不加转换地传送到磁盘文件,因此它又称为内存数据的映像文件.因为文件中的信息不是字符数据,而是字节中的二进制形式的信息,因此它又称为 ...
- .Net Core 图片文件上传下载
当下.Net Core项目可是如雨后春笋一般发展起来,作为.Net大军中的一员,我热忱地拥抱了.Net Core并且积极使用其进行业务的开发,我们先介绍下.Net Core项目下实现文件上传下载接口. ...
- node.js文件系统中同步文件、异步文件、简单文件、流式文件如何写入
文件系统(File System) -文件系统简单来说就是通过Node来操作系统中的文件 -使用文件系统,需要先引入fs模块,fs是核心模块,直接引入不需要下载 一.同步文件的写入 -手动操作的步骤 ...
- Java学习第十六天——字符流读写文件、字符缓冲流拷贝文件
字符流读写文件 字符流读数据-按单个字符读取 创建字符流读文件对象: Reader reader = new FileReader("readme.txt"); 调用方法读取数 ...
- 【思维导图】【标准化、规范化文件】《使用MEEG进行神经成像数据分析和共享的最佳实践》 【脑机接口入门第一篇必备文章】
文档原始下载链接:OSF Preprints | Best Practices in Data Analysis and Sharing in Neuroimaging using MEEG 参考文献 ...
- ajax提交用流的方式,ajax 请求 后台返回的文件流
download(url) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); // 也可以使用POST方式,根据接口 xhr. ...
- AJAX的post请求与上传文件
之前介绍了AJAX的get的请求方式与跨域请求,除此之外AJAX还可以进行异步的post请求,在使用post方式的请求时需要设置请求头,如下: xhr.setRequestHeader("C ...
- 爬虫实战学习笔记_4 网络请求urllib3模块:发送GET/POST请求实例+上传文件+IP代理+json+二进制+超时
1 urllib3模块简介 urllib3是一个第三方的网络请求模块(单独安装该模块),在功能上比Python自带的urllib强大. 1.1了解urllib3 urllib3库功能强大,条理清晰的用 ...
最新文章
- 利用nginx和mongrel、unicorn 对puppet进行端口负载均衡
- maven deploy plugin_学习Maven之Maven Surefire Plugin
- OpenWindow.document.write();
- PHP的构成及生命周期
- 沪江日语电台首度在线直播后续花絮(附直播片段)
- sme是什么职位_学云计算能从事哪些岗位 未来职业发展是什么样
- MySQL server has gone away 问题的解决方法
- 在centos上安装html,Centos-7安装pdf2htmlEX
- C#中只使用Invokerequired来判断是不是UI线程可靠吗?
- 漏洞payload 靶机_hackme:2 靶机攻略
- 学计算机的看图写话,小老鼠上网看图写话
- 这年代,你需要了解一下什么是聚合搜索(附站点推荐)
- Mac 下pyppeteer下载Chromium慢 / pyppeteer下载慢 / Chromium下载慢 / Chromium下载地址
- 化学分子溶解度预测模型(python-Rdkit构建)
- C++读写tif文件
- chrome浏览器打开网页排版错乱
- react(子传父、父传子)
- 基于SSM的快递代取管理系统
- Ubuntu清理系统垃圾 命令
- 【jmeter性能测试】模拟多个IP同时登录
热门文章
- 技术人员兼职招聘平台HourlyHerd融资2200万美元C轮融资
- 如何在Linux上制作一个屏幕录像视频教程
- springMVC一些实践总结
- 安卓--selector简单使用
- ruby on rails 2.3+的版本不再支持cgi
- VMware Workstation 8 技巧集
- [转载] C#面向对象设计模式纵横谈——7. Adapter适配器模式
- 从经理的角度看领域设计
- 为Windows 服务器网络搬家
- 转!最适合新手小白的8个python开发环境(内附python IDE最新下载地址+软件激活码+长期有效)