今日需要对公司的代码进行更新,发现之前有的文件丢失导致下载不到直接跳转到一个空的页面,第一反应是应该没有用异步请求,直接用a标签或者表单之类的处理下载文件请求了。
但是ajax似乎是不支持下载文件的,会把流信息当初文本类处理。。。自然不能还原文件数据。
通过测试发现原生ajax xhlHttpRequest可以处理流信息,具体在于它可以将请求中的数据变成blob对象进行读取(好吧我一个后端的实在是不太清楚前段原理)。。。可以通过判断http的status状态来进行下载文件或者提示错误。
function downloadOnclick() {
var file=$("#realr0205").val();
var fileName=file;
if (file!=undefined&&file!=""&&file.indexOf("/")!=-1){
fileName=file.substr(file.lastIndexOf("/")+1);
}
var url = BASE_PATH+'/manage/filedownload?path='+file;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true); // 也可以使用POST方式,根据接口
xhr.responseType = "blob"; // 返回类型blob
// 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
xhr.onload = function () {
if (this.status == 200) {
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob); // 转换为base64,可以直接放入a表情href
reader.onload = function (e) {
// 转换完成,创建一个a标签用于下载
var a = document.createElement('a');
a.download = fileName;
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
$(a).remove();
}
}else {
//此处是前端layiUI自带的提示框,无视即可
$.confirm({
theme: 'dark',
animation: 'rotateX',
closeAnimation: 'rotateX',
title: false,
content: '未找到该文件',
buttons: {
confirm: {
text: '确认',
btnClass: 'waves-effect waves-button waves-light'
}
}
});
}
};
xhr.send();
}
参考:https://www.cnblogs.com/cdemo/p/5225848.html
另外网上也有一部分人说此方法不安全之类的,缺少判断,容易被网络攻击,我觉得ajax可以带上token,在http协议中加上header信息那原生xhr应该也可以做到吧,既然能做到带上安全验证信息,在后端验证一下不就行了?
还有一部分人认为这样做太麻烦,直接通过A标签或者表单进行实现,我觉得现在基本上哪个功能都会存在错误,存在错误就会产生意料之外的情况,大大降低用户体验感,所以异步请求加判断才是主流。
下面公司之前写法,怪不得拿不到文件就不知道调到哪个页面了。
jQuery.download = function (url, method, filedir) {
jQuery('<form action="' + url + '" method="' + (method || 'post') + '">' + // action请求路径及推送方法
'<input type="text" name="path" value="' + filedir + '"/>' + // 文件路径
'</form>')
.appendTo('body').submit().remove();
//var newTab = window.open('about:blank')
//newTab.location.href = url;
};