遇到的問題:
- 文件下載后文件一直被破壞,無法正常打開
- 文件名亂碼,如圖
剛開始一直在糾結,是不是后端沒有寫對,然后導致下載不能使用
后來搜索了一些資料,發現后端沒什么問題
然后就開始找到其他項目對比下載功能
哈哈哈哈哈哈哈
不會也只能靠這個方法去找問題了,就是有點笨,但總歸找到了問題所在
下載功能后端代碼:
@GetMapping("/annex")public void downloadAnnex(ProcessFindReqVo processFindReqVo, HttpServletResponse response) throws IOException, HttpMediaTypeNotAcceptableException {String filePath = "文件路徑"; // 指定文件路徑if (StringUtils.isBlank(filePath)) {return;}File file = new File(filePath);if (!file.exists()) {return;}response.setCharacterEncoding("utf-8");response.setContentType("application/octet-stream;charset=UTF-8");String fileName = URLEncoder.encode(file.getName(), StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");response.addHeader("Content-Disposition", "attachment;filename=" + fileName);byte[] buffer = new byte[(int)file.length()];FileInputStream fis = null;OutputStream os = null;try {fis = new FileInputStream(file);os = response.getOutputStream();int i = -1;while ((i = fis.read(buffer)) != -1) {os.write(buffer, 0, i);}} catch (IOException ex) {ex.printStackTrace();} finally {if (os != null) {try {os.flush();os.close();} catch (IOException e) {e.printStackTrace();}}if (fis != null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}
下載功能前端代碼
export async function downloadAnnex(data){const res = await axios.get(`/scm/web/monthly/download/annex?id=`+data, {responseType: 'blob'})const content = res.dataconst blob = new Blob([content], { type: 'application/octet-stream' })const contentDispositionHeader = res.headers['content-disposition'];const fileName = contentDispositionHeader.split(';').map(item => item.trim()).find(item => item.startsWith('filename=')).substr('filename='.length);let decodeName = decodeURI(fileName);if ('download' in document.createElement('a')) { // 非IE下載const elink = document.createElement('a')elink.download = decodeNameelink.style.display = 'none'elink.href = URL.createObjectURL(blob)document.body.appendChild(elink)elink.click()URL.revokeObjectURL(elink.href) // 釋放URL 對象document.body.removeChild(elink)} else { // IE10+下載navigator.msSaveBlob(blob, decodeName)}
}
- 說回剛開始的問題,下載時文件始終提示被破壞的原因:
export async function downloadAnnex(data){
這里應該使用async
關鍵字
const res = await axios.get
請求時也應該使用await
關鍵字,這樣就可以使文件順利下載,至于為什么還沒有深究。。。(想以后研究,不知道以后還能不能想起來了😅) - 文件名始終亂碼,就使用
decodeURI(fileName);
進行解碼,之后就可以正確的展示中文字符了,前提時后端傳輸時已經設置了UTF-8
的編碼