网页传统下载文件的方式,是直接open一个新的页面。但有时我们希望在网页内下载文件,然后再处理(或者弹出下载窗口)。特别是,下载的文件需要使用非GET请求,携带头部信息等,而传统的下载方式是无法实现的。这时就不能直接使用open打开下载地址,而是使用异步请求来实现这个需求。
注意,jquery的异步接口无法实现blob数据下载。若下载的数据需要blob类型,例如图片,请使用XMLHttpRequest。
以下是我的cdn网页设计的下载方案。大家可以参考一下。我这个下载就是需要携带令牌的头部信息,所以直接打开是无法实现的。这时就得使用异步下载。另外,我下载文件后,是弹出下载窗口。对于想在网页内弹出下载窗口保存文件,实现方式就是里面的保存逻辑。有些人是下载文件后,用于页面内处理,例如显示图片,这时就不是保存逻辑,记得换成自己的方案。下载过程可能需要很长时间,所以我使用$.notify提示一下。由于代码很简单,我就不加注释。有什么疑问,再提问~
附上我的cdn地址:
http://www.iot2ai.top/operation/disk.html
function openDownload(url, name, token) {
var notifyE = $.notify({
message: "正在下载“" + name + "”",
icon: 'fa fa-spinner fa-spin'
}, {
type: 'info'
});
// CAUTION: $.ajax cannot download blob! please use XMLHttpRequest!
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
if (token) xhr.setRequestHeader('x-access-token', token);
// set response type, or it will be parsed!!
xhr.responseType = 'blob';
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
notifyE.close();
if (xhr.status === 200) {
// done
if (ctrlFileReply) {
if (window.opener && window.opener.isReceivingData) {
sendToReceiver(url, xhr.response);
return;
}
}
// redefine blob type to download!!
var b = new Blob([xhr.response], {
type: 'application/octet-stream'
});
var u = URL.createObjectURL(b);
var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
save_link.href = u;
save_link.download = name;
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
save_link.dispatchEvent(event);
URL.revokeObjectURL(u);
} else if (xhr.status === 404) {
// not found
$.notify({
message: "“" + name + "”无法找到!",
icon: 'fa fa-check'
}, {
type: 'danger'
});
} else {
// fail
handleFail(xhr);
}
}
};
xhr.send();
}