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

环境说明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);
        }
    }

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

相关推荐
emojiwoo13 分钟前
前端视觉交互设计全解析:从悬停高亮到多维交互体系(含代码 + 图表)
前端·交互
xxy.c15 分钟前
嵌入式解谜日志—多路I/O复用
linux·运维·c语言·开发语言·前端
yuehua_zhang1 小时前
uni app 的app端 写入运行日志到指定文件夹。
前端·javascript·uni-app
IT_陈寒1 小时前
SpringBoot 3.x实战:5种高并发场景下的性能优化秘籍,让你的应用快如闪电!
前端·人工智能·后端
麦文豪(victor)1 小时前
自动化流水线
前端
JarvanMo3 小时前
Flutter. FractionallySizedBox
前端
知识分享小能手4 小时前
React学习教程,从入门到精通, React 入门指南:React JSX 语法知识点详解及案例代码(8)
前端·javascript·vue.js·学习·react.js·前端框架·anti-design-vue
卓码软件测评4 小时前
第三方web测评机构:【WEB安全测试中HTTP方法(GET/POST/PUT)的安全风险检测】
前端·网络协议·安全·web安全·http·xss
学习3人组4 小时前
React 组件基础与事件处理
前端·javascript·react.js
漂流瓶jz9 小时前
解锁Babel核心功能:从转义语法到插件开发
前端·javascript·typescript