鍍金池/ 問答/Java  HTML/ vue+axios下載文件提示已損壞無法打開

vue+axios下載文件提示已損壞無法打開

問題描述

前后端分離,文件下載后損壞
clipboard.png

google、度娘了一大堆,大致手段都下面這些
https://www.cnblogs.com/sunsh...
https://blog.csdn.net/u010986...
https://blog.csdn.net/qq_3837...
https://github.com/axios/axio...
還是解決不了,只好來求助了

后端接口代碼:

@ApiOperation(value="下載附件", notes="根據(jù)附件路徑下載附件")
@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);
    }
}

在具體組件中導(dǎo)入方法傳入附件路徑進(jìn)行下載,結(jié)果下載下來后打不開。
難道是后端返回有問題?但是我把header中的token認(rèn)證去掉后直接使用瀏覽器請求接口是能下載下來也能打開的。

另外在這里也找到個(gè)說法,說是二進(jìn)制數(shù)據(jù)被轉(zhuǎn)換成文本導(dǎo)致數(shù)據(jù)被破壞,難道還是axios用得不對(duì)?求指教

回答
編輯回答
拼未來

下載個(gè)文件搞這么復(fù)雜干什么啊,直接返回下載連接不就好了

就算按你的方法,你想通過返回blob,然后下載,也沒有這么煩麻啊,簡單例子給你一枚

axios.get('http://127.0.0.1/1.XLS', { //沒心情還去實(shí)現(xiàn)一次服務(wù)端,直接用一個(gè)服務(wù)器上的靜態(tài)文件給你做演示
                responseType: 'blob' //返回?cái)?shù)據(jù)的格式指定為blob
            })
            .then(response => {
                console.log(response);
                let url = window.URL.createObjectURL(response.data); //創(chuàng)建一個(gè)新的 URL 對(duì)象
                console.log(url)
                //以下代碼一句話解釋,在頁面上生成一個(gè)a標(biāo)簽并指定href為上面的url,然后模擬點(diǎn)擊,以實(shí)現(xiàn)自動(dòng)下載
                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(`接口調(diào)用失敗`);
               
                console.log(err);
            })
2017年6月7日 14:33
編輯回答
嘟尛嘴

不知樓主是否解決,遇到相同的問題!

2018年1月11日 12:49