a标签/js下载文件(2020)

本文介绍了前端如何处理文件下载,分为二进制式下载和URL下载两种方式。二进制式下载涉及responseType、Content-Type和Content-Disposition的设置,URL下载则依赖a标签的href和download属性,同时讨论了跨域文件下载的解决方案。
摘要由CSDN通过智能技术生成


主要参考【前端:下载文件实现方式及跨域下载(详解) https://blog.csdn.net/qq_43471802/article/details/103436595】
加上自己遇到的问题,记录并分享,如有错误,请指正

下载文件根据后端返回的是文件流还是URL下载url地址,主要分两种:

  • 二进制式下载
  • URL下载

一、二进制式下载

如果后端返回二进制文件流,前端需要使用Blob接收

1、responseType(请求)

首先在前端发送请求时就应在请求头中,用responseType告知服务器需要返回的数据类型,responseType默认是“json”,这里我们请求的是文件流:“blob”

不同的请求插件设置header的方式不同,用axios来说,axios.post(url, data, config),responseType是在config里设置的(这些设置应该是在底层赋给请求头):

export function download(url, data) {
   
    return axiosInstance.post(url,data,{
   
            responseType: 'blob'
        }
    );
}

如果这里不定义responseType,下载下来的文件内容会乱码

2、Content-Type(响应)判断是普通数据还是文件流(可选)

服务器返回不同数据,我们会做不同的处理,json我们直接取用,文件流数据需处理后下载。

在axios项目中,一般为了给所有的请求做一些统一处理,比如baseURL、请求带token,回包错误码提示,在底层封装一个axios实例,所有的请求都调用该实例的方法。

这种情况下,文件的请求就有可能和普通数据的请求调用的是同一个实例。直接在总响应拦截器里判断出文件流并执行下载,就不用在每一文件请求协议回调里各自再写一遍执行下载的代码。如何区分响应数据的是文件流还是json数据就很有必要了。

头部Content-Type表示服务端发送的类型及采用的编码方式,一般为application/json.而回包是文件,则Content-Type 一般为“octets/stream”,我们就以此判断是返回的是文件还是普通数据。

//axios响应拦截器里
if(res.headers &&
  (res.headers['content-type'].indexOf('application/x-msdownload') != -1 ||
    res.headers['content-type'].indexOf('octets/stream') != -1 ||
    res.headers['content-type'].indexOf('application/octet-stream') != -1)){
   
   //执行下载方法
}

3、Content-Disposition(响应)和文件名(可选)

还是针对第2节所描述的情况:判断出来什么时候是文件数据,在回包里拿到整个文件,而文件名就需要从响应头里的Content-Disposition属性获取
【官方文档:Content-Disposition

Content-Disposition可以出现在消息主体中, 也可以出现在multipart/form-data类型的应答消息体中。Content-Disposition在不同的地方有不同的作用和意义,而文件下载属于前者,下面我们也只说第一种。

在常规的HTTP应答中,Content-Disposition在响应头,有两个参数。第一个参数用于指示回复的内容该以何种形式展示:

  • inline — 默认值,内联形式。表示回复中的消息体会以页面的一部分或者整个页面的形式展示)
  • attachment附件形式。意味着消息体应该被下载到本地,大多数浏览器会自动触发一个“保存为”的对话框,将filename的值预填为下载后的文件名,假如它存在的话
    当第一个参数为attachment 时才有第二个参数——filename

这里Content-Disposition应为attachment,文件名就在第二个参数里:
在这里插入图片描述
我们可以从参数里分离出文件名:


                
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值