这种方式不需要后端协助,具体代码如下:
// fileUrl为空不写时默认url就是前端目前打开页面的url
// fileUrl 写了东西默认也是拼接在起服务的url后面,例如本地起的前端页面,fileUrl会自动填充http://localhost:8080/ + fileUrl
// 要想fileUrl完全自己控制,就需要填写完整url,从http开始,例如:http://123.32.21.12:4688/ + 文件路径
let fileUrl = '';
let aLink = document.createElement('a');
aLink.style.display = 'none';
aLink.href = fileUrl;
aLink.setAttribute('download', fileName) // fileName 自定义文件名
document.body.appendChild(aLink);
aLink.click(); // 执行a标签的点击事件,不加下载不起作用
document.body.removeChild(aLink);
注意
:如果fileUrl完全是自己通过后端传的url+文件路径进行拼接的,那么通过a链接的download属性改文件名可能就会失效,因为图片可能是另外服务器上的,下载到本地改名也是应该改远程,但是因为在本地和远程url不一致,由于不同源,相当于跨域修改,所以不成功。
这种方式后端传来的数据一般都是文件流,需要通过一些方式转换下,再继续通过a链接进行下载,代码如下:
const instance = axios.create({
baseURL: "http://192.168.43.55:8000",
timeout: 5000,
responseType: 'blob' // 这个不设置会导致接受的文件流能下载但无法打开,设置后后端返回的文件流会自动保存在返回信息的data中
});
// url: 后端接口地址 param: 所需参数
this.axios.post(url, param)
.then(res => { // res保存的是接口的一些信息包括状态码status,config,data等一些信息,文件流默认存在data中
let blob = new Blob([res.data]);
let blobUrl = window.URL.createObjectURL(blob);
// 转换完成就跟第一种情况一致,通过a链接下载
let aLink = document.createElement('a');
aLink.style.display = 'none';
aLink.href = blobUrl;
aLink.setAttribute('download', fileName)
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
window.URL.revokeObjectURL(blobUrl) // 前面创建的url地址最后也要去掉,为了安全和性能
})
.catch(e => console.log(e))
new Blob
是用来处理后端返回文件流的,使用这个必须把请求中responseType: blob
设置下,第一个参数是数组,里面存放后端返回的数据流,第二个参数type属性是用来看需要导出的文件是何种格式的,具体如下:
导出excel格式: new Blob([res], {type: 'application/vnd.ms-excel'})
导出word格式: new Blob([res], {type: 'application/msword'})
导出.zip格式: new Blob([res], {type: 'application/zip'})
导出.xls或者.xlsx new Blob([res], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})