ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践

写在前面 :从提出需求到完美的解决问题,实现过程是曲折的。

需求:在前(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 使用指南

分类: html5 css3,javascript

原文地址:https://www.cnblogs.com/lguow/p/9376497.html

时间: 2024-10-01 06:13:35

ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践的相关文章

c文件二进制读取写入文件、c语言实现二进制(01)转化成txt格式文本、c读取文件名可变

c语言实现二进制(01)转化成txt格式文本: 下面的程序只能实现ascall对应字符转换,如果文件内出现中文字符,则会出现错误. 本程序要自己创建个文本格式的输入文件a1.txt,编译后能将文本文件前255字节以内的字符转换成相应的AscII码值的二进制表示,并存入输出文件a2.txt中.然后再将二进制文件还原并存入b2.txt文件. 参考链接:https://www.jb51.net/article/158695.htm 1 #include <cstdio> 2 #include <

.Net Core 图片文件上传下载

当下.Net Core项目可是如雨后春笋一般发展起来,作为.Net大军中的一员,我热忱地拥抱了.Net Core并且积极使用其进行业务的开发,我们先介绍下.Net Core项目下实现文件上传下载接口. 一.开发环境 毋庸置疑,宇宙第一IDE VisualStudio 2017 二.项目结构 FilesController 文件上传下载控制器 PictureController 图片上传下载控制器 Return_Helper_DG 返回值帮助类 三.关键代码 1.首先我们来看Startup.cs

框架基础:ajax设计方案(六)--- 全局配置、请求格式拓展和优化、请求二进制类型、浏览器错误搜集以及npm打包发布

距离上一次博客大概好多好多时间了,感觉再不搞点东西出来,感觉就废了的感觉.这段时间回老家学习驾照,修养,然后7月底来上海求职(面了4家,拿了3家office),然后入职同程旅游,项目赶进度等等一系列的原因,导致没有太多时间去搞东西.感觉亏欠了好多,所以这次一次性补上.废话不多说了,我们直接进入主题. 介绍这次讲解的库的更新: ajax全局配置 请求参数的拓展(增加json)和重构优化 初始化参数类型检查 浏览器错误回收机制 增加ajax请求blob(二进制)类型 跨域问题的总结和支持 npm打包

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

时间有限,废话就不多说了,直接上干货! 下面给大家介绍一下我遇到的一个坑,如果你也遇到了,那恭喜你,你一定能找到答案:angular2/angular4 如何通过$http的post方法请求下载二进制的Excel文件? (angular1自行百度) 问题描述: 后台返回的是一个二进制的Excel流,请求头如下: Access-Control-Allow-Origin:* Cache-Control:private Content-Disposition:attachment;filename=%

减少HTTP请求之将图片转成二进制并生成Base64编码,可以在网页中通过url查看图片(大型网站优化技术)

原文:减少HTTP请求之将图片转成二进制并生成Base64编码,可以在网页中通过url查看图片(大型网站优化技术) 在网站开发过程中,对于页面的加载效率一般都想尽办法求快.那么,怎么让才能更快呢?减少页面请求 是一个优化页面加载速度很好的方法.上一篇博文我们讲解了 “利用将小图标合成一张背景图来减少HTTP请求”,那么,这一篇博文将讲解  “ 将图片转成二进制并生成Base64编码,可以在网页中通过url查看图片”. 一.为何选择将图片转成二进制并生成Base64编码,可以在网页中通过url查看

ajax请求过程中下载文件在火狐下的兼容问题

项目中碰到的问题,记录如下. 需求很简单,点击一个文件链接下载该文件,同时向后台发送请求.需求很常见,用户点击下载后通常要进行下载量的统计,统计的话可以利用 script标签 或者 img标签(图片ping) 的跨域能力,将它们的 src 属性指向统计地址,但是这次用了 ajax 进行统计,遂出现了这个问题. demo 代码如下: 复制代码<a id="a" href="http://c758482.r82.cf2.rackcdn.com/Sublime Text 2.

使用FormData,进行Ajax请求并上传文件

使用FormData,进行Ajax请求并上传文件 这里使用JQuery,但是老版本的JQuery比如1.2是不支持的,最好使用2.0或更新版本: Html代码 <form id= "uploadForm"> <p >指定文件名: <input type="text" name="filename" value= ""/></p > <p >上传文件: <inpu

框架基础:ajax设计方案(一)---集成核心请求

框架基础:ajax设计方案(一)---集成核心请求 框架基础:ajax设计方案(一)---集成核心请求 报告,我要说话!xp被历史淘汰了,IE6 say goodbye了,太TM开心了,从此不要兼容IE6了,哈哈哈哈哈哈 报告,我要说话!IE这sb为啥不早点被杀掉呢,找工作听说要兼容IE,立马软了,唉唉唉唉唉唉 报告,我要说话!Jquery太丰富了,老子只用了几个功能,妈的,太不划算了,啊啊啊啊啊啊 ...... 好了,言归正传.对于想到整理ajax设计方案,原因如下: 从资源合理利用的角度以及

c#代码,模拟form表单发送post请求,上传文件(并带其他参数)

本人对post理解不深,前段时间遇到一个需要用c#代码发送post请求上传文件的业务,于是参考了几篇帖子,加上自身实践写出了如下代码.写的比较low 望各位大大指正^_^. 业务需求: 对方给了一个接口,让传四个参数分别为"modelId.fileContent.updateTime.encrypt" 其中modelId.updateTime.encrypt 都是普通的字符串类型.fileContent则是二进制文件 我实在是不了解post的相关知识,平时只是普通的用法,没有深层看过相