vue+axios下载文件提示已损坏无法打开

问题描述

前后端分离,文件下载后损坏
clipboard.png

google、度娘了一大堆,大致手段都下面这些
https://www.cnblogs.com/sunsh...
https://blog.csdn.net/u010986...
https://blog.csdn.net/qq_3837...
axios/axios/issues/815" rel="nofollow">https://github.com/axios/axio...
还是解决不了,只好来求助了

后端接口代码:

@ApiOperation(value="下载附件", notes="根据附件路径下载附件")

@GetMapping("/download")

public ResponseEntity<byte[]> download(String path) throws UnsupportedEncodingException{

if (fastDFSClient.getFileInfo(path) != null)

{

byte[] buffer = fastDFSClient.downloadFile(path);

HttpHeaders headers = new HttpHeaders();

headers.add("Content-Disposition","attachment;filename=" + FileUtil.getOriginalFilename(path));

headers.add("Content-Length", "" + buffer.length);

List<String> hlist = new ArrayList<String>();

hlist.add("Content-Disposition");

hlist.add("Content-Length");

headers.setAccessControlExposeHeaders(hlist);

return ResponseEntity.ok()

.headers(headers)

.contentLength(buffer.length)

.contentType(MediaType.APPLICATION_OCTET_STREAM)

.body(buffer);

}

return this.Resp423(null);

}

前端下载工具方法

import axios from 'axios';

import store from '../store';

import fileDownload from 'js-file-download'

export async function download(path) {

const res = await axios({

baseURL: process.env.BASE_API,

timeout: 2 * 60 * 60 * 1000,

headers:{'token':store.getters.token},

url:process.env.ServerName_COMMON+"/file/download",

method:"get",

params:{path:path},

responseType: "blob"

});

let disposition = res.headers['content-disposition'];

let filename = decodeURI(disposition.replace("attachment;filename=",""));

let fileType=res.headers['content-type'];

let resBlob = res.data;

let resData = null;

try {

let resText = await new Promise((resolve, reject) => {

// 通过 FileReader 接受并解析

let reader = new FileReader();

reader.addEventListener('abort', reject);

reader.addEventListener('error', reject);

reader.addEventListener('loadend', () => {

resolve(reader.result);

});

// 文件

reader.readAsText(resBlob);

});

resData = JSON.parse(resText);

} catch (err) {

}

if (resData) {

if (resData.error) {

} else {

}

} else {

fileDownload(resBlob, filename);

}

}

在具体组件中导入方法传入附件路径进行下载,结果下载下来后打不开。
难道是后端返回有问题?但是我把header中的token认证去掉后直接使用浏览器请求接口是能下载下来也能打开的。

另外在这里也找到个说法,说是二进制数据被转换成文本导致数据被破坏,难道还是axios用得不对?求指教

回答:

responseType: 'blob'要和params放在一个对象里,不要放到第3个参数

回答:

下载个文件搞这么复杂干什么啊,直接返回下载连接不就好了

就算按你的方法,你想通过返回blob,然后下载,也没有这么烦麻啊,简单例子给你一枚

axios.get('http://127.0.0.1/1.XLS', { //没心情还去实现一次服务端,直接用一个服务器上的静态文件给你做演示

responseType: 'blob' //返回数据的格式指定为blob

})

.then(response => {

console.log(response);

let url = window.URL.createObjectURL(response.data); //创建一个新的 URL 对象

console.log(url)

//以下代码一句话解释,在页面上生成一个a标签并指定href为上面的url,然后模拟点击,以实现自动下载

var a = document.createElement("a");

document.body.appendChild(a);

a.href = url;

a.download = '2.xls';

a.click();

window.URL.revokeObjectURL(url);

})

.catch(err => {

console.log(`接口调用失败`);

console.log(err);

})

回答:

https://segmentfault.com/q/10...
把mock关掉试下

回答:

不知楼主是否解决,遇到相同的问题!

回答:

同样的问题难受

回答:

通过a标签直接下载可以打开 也没有乱码

<a                    :href="`${basefileupload}base/api/userInfo/teacherInfo/downloadExcelTemplate?orgId=${myorgId}`"

class="please-important-module"

>导入模板下载</a>

但是现在需要token,就无法直接使用a标签了。按照上面说的方式,仍然有乱码

回答:

同样的问题 难受~~

你可以试下这个方法:

downloadHandle(){

let itemData = {

ptojeatId:this.ptojeatId

}

AgementList(this.ptojeatId).then(response => {

let bob = new Blob([response],{

type:'application/zip' (我们后端下载个格式是zip)

});

let objectUrl =URL.createObjectURL(blob);

location.href = objectUrl;

URL.revokeObjectURL(objectUrl);

}).catch(err => {

console.log('下载错误')

})

}

重点来了 调接口的时候要配置:

export function(ptojeatId){

return request({

methods:'get',

url:"",

params:{

ptojeatId:ptojeatId

},

response:'arraybuffer'

})

}

回答:

删除mockjs!
删除mockjs!
删除mockjs!

还有比我更惨的吗?
我在项目中使用了mockjs,这个垃圾框架会修改后端返回的数据,我整整浪费了两天时间!哎。。。

以上是 vue+axios下载文件提示已损坏无法打开 的全部内容, 来源链接: utcz.com/a/149992.html

回到顶部