一、场景
在jQuery+HTML的前端项目中,想要实现通过接口获取文件并预览。
例如:档案管理需要上传附件,产品要求 —— 上传后的附件支持预览。于是,我先采用iframe展示文件缩略图,再通过【点击预览】按钮,打开新标签页展示文件内容。
二、问题描述
在实现预览时发现,ajax发出请求后获取到的数据是乱码字符串。
于是,我在网上查询了一些方法,包括设置headers、responseType等,结果并未改变。发出的请求始终都返回上图里的乱码字符串。
三、调研过程
显然,问题出在ajax上。这时我找到了一篇题为 前端接收数据实现图片预览效果–ajax请求二进制流 的文章,文章中详细描述了和我相似的问题。于是我参考他的解决方法进行调整:
3.1 确定根因
通过jQuery官网里的ajax api了解到,datatype的数据类型默认以string返回,且另外支持xml, json, script, text, html。也就是说,当接口请求文件时,就算是二进制流也会按照字符串返回。
3.2 另寻他法
既然ajax不能用,那就回到原生XHR,从底层改写返回类型。参考:XHR responseType官网API
现在成功返回了Blob对象,接下来就是利用这个文件对象创建DOM并返回URL,就能用window.open直接打开。
var xhr = new XMLHttpRequest();
xhr.open('GET', '/rpsm-web' + fileurl);
xhr.responseType = 'blob';
xhr.onload = function (){
var PDFurl = window.URL.createObjectURL(xhr.response);
window.open(PDFurl);
};
xhr.send();
3.3 解析方法
从我的理解上讲,ajax基于XHR封装,而封装内容里限制了XHR的responseType。
所以在需要用到二进制文件上传/下载时,就不能依赖于jQuery的ajax,而必须 根据XHR重新封装自己的ajax对象 or 直接调用XHR请求 。
四、总结
一直使用jQuery、调用jQuery的ajax,其实始终未理解本质,这也是导致前期调研不断试错的原因。往后还是要多学习多领悟,从入门到入土 —— ( •̀ ω •́ )