vue项目中下载文件踩过的坑(一)
很多的系统管理端会有文件上传或者下载功能,那么在文件上传和下载的时候我们又会遇到什么样的坑人的意外呢?
昨天我们在做管理系统的文件下载时,遇到了这么一个问题。因为文件名是后端提供,所以返回在了响应头的Content-Disposition中,但是因为这个字段并不是默认暴露的字段,所以需要后端做暴露(加上这句代码)
Access-Control-Expose-Headers: Content-Disposition
在前端接收到后端暴露的响应头字段时,在请求拦截器中拿到并处理返回数据
1 service.interceptors.response.use( 2 response => { 3 if (response.request.responseType === 'arraybuffer' && !response.headers['content-disposition']) { 4 //当没有content-disposition这个字段时return的数据 5 return response.data 6 } 7 if (response.request.responseType === 'arraybuffer' && response.headers['content-disposition']) { 8 //当存在content-disposition这个字段时,return出来的数据 9 const temp = {} 10 temp.data = response.data 11 temp.filename = response.headers['content-disposition'] 12 return temp 13 } 14 const res = response.data 15 if (res.success) { 16 return response.data 17 } else { 18 Message({ 19 message: res.message, 20 type: 'error', 21 duration: 5 * 1000 22 }) 23 return Promise.reject(res.message) 24 } 25 } 26 )
当我们下载文件时返回了文件名,下载文件模板时没有返回文件名
1 getDocData(data) { 2 const params = { 3 id: data 4 } 5 GiftApi.exportDoc(params).then(res => { //返回文件名的写法 6 this.content = res.data 7 const filename = res.filename.split(';')[1].split('=')[1] 8 this.filename = decodeURI(filename) 9 const blob = new Blob([this.content]) 10 if (window.navigator.msSaveOrOpenBlob) { 11 // 兼容IE10 12 navigator.msSaveBlob(blob, this.filename) 13 } else { 14 // chrome/firefox 15 const aTag = document.createElement('a') 16 aTag.download = this.filename 17 aTag.href = URL.createObjectURL(blob) 18 aTag.click() 19 URL.revokeObjectURL(aTag.href) 20 } 21 }) 22 } 23 24 getDocData(data) { 25 const params = { 26 id: data 27 } 28 GiftApi.exportDoc(params).then(res => { //未返回文件名的写法 29 this.content = res 30 this.filename = this.temp.name + '.doc' 31 const blob = new Blob([this.content]) 32 if (window.navigator.msSaveOrOpenBlob) { 33 // 兼容IE10 34 navigator.msSaveBlob(blob, this.filename) 35 } else { 36 // chrome/firefox 37 const aTag = document.createElement('a') 38 aTag.download = this.filename 39 aTag.href = URL.createObjectURL(blob) 40 aTag.click() 41 URL.revokeObjectURL(aTag.href) 42 } 43 }) 44 }
这样的代码本身没有错误,而且在本地和测试服务器上测试的时候也没有问题,但是打包之后的测试会存在问题,就是未返回文件名的接口下载的文件,打开会出现[object,object],而不是我们文件原本的内容。所以我的解决方法就是让后端统一返回文件名并把该字段暴露出来让前端能获取到,渲染和处理数据的格式一样,就不会出现打包之后下载文件出错的问题