1. 链接下载文件


//该方法火狐有些版本是不支持的
window.location.href=url

//为了解决火狐有些版本不支持,可以改成这种方式
window.location=url

//该方法在火狐上没有效果的,在IE浏览器上是可以的
window.open(url, '_blank') // 打开新窗口
  • 优点: 兼容性良好,代码简洁;
  • 缺点:
    • URL长度有限制;
    • 拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示

2. iframe 下载文件

try {
	const elemIF = document.createElement('iframe')
	elemIF.src = url //url为后端返回路径
	elemIF.style.display = 'none'
	document.body.appendChild(elemIF)
	// 防止下载两次
	setTimeout(() => {
		document.body.removeChild(elemIF)
	}, 1000)
} catch (e) {
	console.log(e)
}
  • 优点: 兼容性良好,代码简洁;
  • 缺点:
    • URL长度有限制;
    • 拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示;
    • URL长度有限制;

3. HTML5 新增download属性

这个属性很重要,它可以指定下载文件名,并且可以告诉浏览器目标链接是一个下载链接,不是一个普通链接,我们看下面代码就能看出区别了:

<a href="data:text/txt;charset=utf-8,测试下载纯文本" download="测试.txt" >下载1</a>
<a href="data:text/txt;charset=utf-8,测试下载纯文本">下载2</a>

可以发现,下载1按钮能够实现下载,点击下载2链接时直接在浏览器打开文件内容了。

4. 后端返回Blob对象

function download(content, filename) {
    // 字符内容转变成blob地址
    var blob = new Blob([content]);
    if('msSaveOrOpenBlob' in navigator){ //兼容IE
        window.navigator.msSaveOrOpenBlob(blob, filename);
        return;
    }
    var eleLink = document.createElement('a');
    eleLink.download = filename;
    $(eleLink).css('display', 'none');
    eleLink.href = URL.createObjectURL(blob);
    document.body.appendChild(eleLink);
    eleLink.click();
    document.body.removeChild(eleLink);
};

5. axios(ajax)前端根据返回数据流生成文件下载

axios.post(url, param, {
  responseType: 'blob'
}).then((res) => {
  console.log('res', res);
  const blob = res.data;
  const reader = new FileReader();
  reader.readAsDataURL(blob);
  reader.onload = (e) => {
    const a = document.createElement('a');
    a.download = `文件名称.zip`;
    // 后端设置的文件名称在res.headers的 "content-disposition": "form-data; name=\"attachment\"; filename=\"20181211191944.zip\"",
    a.href = e.target.result;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };
}).catch((err) => {
  console.log(err.message);
});

参考1
参考2

07-23 04:19