前端下载文件后,文件损坏,无法打开?

环境说明vue axios + java springboot

我们在开发项目经常遇到的需求是 文件上传下载,这篇文章将重点介绍 文件下载遇到的各种问题以及解决方案

1.在前端请求中参数 responseType 是指 期望的响应类型,决定了如何处理服务器返回的数据,常见的有 arraybuffer,blob,stream

2.接受到后端返回的数据后,定义的type: contentType

const blob = new Blob([response.data],{ type: contentType });

对应后端 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

常见的值有 application/octet-stream,application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 等,如果不定义或者前后端定义不一致都会导致前端能接受到文件,但是打开文件时报错文件损坏

3.还有有时候会碰到跨域问题,跨域设定完毕后一定要刷新页面(即使修改的后端),很多时候明明设定都调整好了,页面就是报错,很可能就是没有刷新页面导致的

附上代码

export function httpDownFile({ httpUrl, httpParams,httpResponseType}) {
    if(!httpResponseType){
        httpResponseType = 'blob'
    }
    axios({
        method: 'get',
        url: httpUrl,
        params:httpParams,
        responseType: httpResponseType
    }).then(function (response) {
        console.log("文件下载成功");
        //获取后端返回的数据类型
        const contentType = response.headers['content-type'];
        // 从Content-Disposition头中提取文件名
        const contentDisposition = response.headers['content-disposition'];
        const filenameMatch = contentDisposition.match(/filename\*=UTF-8''(.*)/);
        const filename = decodeURIComponent(filenameMatch[1]);
        const blob = new Blob([response.data],{ type: contentType });
        const downloadUrl = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.download = filename;
        document.body.appendChild(link);
        link.click();
        window.URL.revokeObjectURL(downloadUrl);
    }).catch(function (error) {
        console.log(error);
    });
}

调用

  httpDownFile({
    httpUrl:'/file/excel',
    httpParams:{
      "name":'aaa'
    },
    httpResponseType:'blob'
  })

后端

    @GetMapping("/file/excel")
    public ResponseEntity<byte[]> selectSql1(@RequestParam String name) {
        try (Workbook workbook = new XSSFWorkbook(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            // 创建工作表和数据
            Sheet sheet = workbook.createSheet("示例数据");
            Row row = sheet.createRow(0);
            row.createCell(0).setCellValue("编号");
            row.createCell(1).setCellValue("姓名");
            row.createCell(2).setCellValue("自定义参数");

            // 添加示例数据
            Row dataRow = sheet.createRow(1);
            dataRow.createCell(0).setCellValue(1);
            dataRow.createCell(1).setCellValue("张三");
            dataRow.createCell(2).setCellValue(name); // 使用请求参数填充数据

            // 写入数据到流
            workbook.write(outputStream);

            // 构造响应
            byte[] excelData = outputStream.toByteArray();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentDispositionFormData("attachment", "example.xlsx");
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(excelData);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }

好了,你还遇到过哪些离谱的问题,留言给我吧

相关推荐
Jiaberrr8 分钟前
微信小程序中 crypto-js 加解密全攻略
前端·javascript·vue.js·微信小程序·小程序
cwtlw1 小时前
CSS学习记录11
前端·css·笔记·学习·其他
曼陀罗2 小时前
import 一个js文件,报ts类型错误的解决思路
前端·typescript
轻动琴弦2 小时前
nestjs+webpack打包成一个mainjs
前端·webpack·node.js
m0_748236112 小时前
前端怎么预览pdf
前端·pdf
快乐牛牛不要困难2 小时前
前端将base64转pdf页面预览
前端
m0_748233642 小时前
Python Flask Web框架快速入门
前端·python·flask
凉辰2 小时前
使用FabricJS对大图像应用滤镜(巨坑)
前端
梓沂2 小时前
pom.xml中dependencyManagement的作用
xml·java·前端
m0_748250032 小时前
前端pdf预览方案
前端·pdf·状态模式