前端接收数据流实现图片预览效果--ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践

简介: 本文为转载文章原文链接:https://www.cnblogs.com/cdemo/p/5225848.html首先要谢谢这位大神的无私贡献!解决了我的问题也完美表达了我当时的心路历程ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践写在前面 :从提出需求到完美的解决问题,实现过程是曲折的。

本文为转载文章

原文链接:https://www.cnblogs.com/cdemo/p/5225848.html

首先要谢谢这位大神的无私贡献!解决了我的问题也完美表达了我当时的心路历程大笑大笑

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 使用指南

 

自己总结的一点问题:

如果在检查代码发现代码无误,却始终发现预览效果为空白时请确认一下请求路径下的图片否确实存在

目录
相关文章
|
1月前
|
XML 前端开发 JavaScript
|
3天前
|
JSON 前端开发 JavaScript
Python中如何判断是否为AJAX请求
AJAX请求是Web开发中常见的异步数据交互方式,允许不重新加载页面即与服务器通信。在Python的Django和Flask框架中,判断AJAX请求可通过检查请求头中的`X-Requested-With`字段实现。Django提供`request.is_ajax()`方法,Flask则需手动检查该头部。本文详解这两种框架的实现方法,并附带代码示例,涵盖安全性、兼容性、调试及前端配合等内容,帮助开发者提升Web应用性能与用户体验。
20 0
|
2月前
|
JSON JavaScript 前端开发
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
73 22
|
2月前
|
前端开发 JavaScript
回顾前端页面发送ajax请求方式
回顾前端页面发送ajax请求方式
43 18
|
2月前
|
前端开发 JavaScript Java
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
95 4
|
2月前
|
前端开发 JavaScript 数据处理
JQuery 拦截请求 | Ajax 请求拦截
【10月更文挑战第4天】
134 1
|
3月前
|
前端开发
React技术栈-react使用的Ajax请求库实战案例
这篇文章介绍了在React应用中使用Axios和Fetch库进行Ajax请求的实战案例,展示了如何通过这些库发送GET和POST请求,并处理响应和错误。
63 10
|
3月前
|
前端开发
React技术栈-react使用的Ajax请求库用户搜索案例
这篇文章展示了一个React技术栈中使用Ajax请求库(如axios)进行用户搜索的实战案例,包括React组件的结构、状态管理以及如何通过Ajax请求获取并展示GitHub用户数据。
37 7
React技术栈-react使用的Ajax请求库用户搜索案例
|
3月前
|
JSON JavaScript 前端开发
Jquery常用操作汇总,dom操作,ajax请求
本文汇总了jQuery的一些常用操作,包括DOM元素的选择、添加、移除,表单操作,以及如何使用jQuery发送Ajax请求,涵盖了GET、POST请求和文件上传等常见场景。
|
3月前
|
JSON 资源调度 JavaScript
Vue框架中Ajax请求的实现方式:使用axios库或fetch API
选择 `axios`还是 `fetch`取决于项目需求和个人偏好。`axios`提供了更丰富的API和更灵活的错误处理方式,适用于需要复杂请求配置的场景。而 `fetch`作为现代浏览器的原生API,使用起来更为简洁,但在旧浏览器兼容性和某些高级特性上可能略显不足。无论选择哪种方式,它们都能有效地在Vue应用中实现Ajax请求的功能。
51 4