post请求下载文件,ajax

         在这里当时想着生成pdf的请求为post,获取pdf的请求为get,通过全局变量filename来获取pdf,但是这里存在着线程安全问题,全局变量会被不同的用户更改,下载时可能会下载到另外一个用户所生成的文件。

        处理办法是,把生成pdf和下载pdf合并成同一个接口,这样避免了上述情况的发生,但是在前台浏览器获取pdf出现了问题,浏览器通过get请求可以直接下载文件(弹出下载框),但是这个接口是需要要是post请求(传递实体类),所以通过前台的数据处理和后台的返回头setHeader设定解决了这个问题。

通过异步的post请求,返回数据浏览器不会自动下载,需要在前端异步请求做处理

axios.post("http://localhost:8080/satable/pdf", param,{responseType:'blob'}).then(res => {
                        const name = res.headers['content-disposition'];
                        let fileName = '';
                        if (name) {
                            const str1 = name.replace(' ', '');
                            const arr1 = str1.split(';');
                            arr1.some(item => {
                                if (item.indexOf('filename') != -1) {
                                    fileName = item.split('=')[1];
                                }
                                return item.indexOf('filename') != -1;
                            });
                            if (fileName === ''){
                                fileName = 'excel.pdf'
                            }
                        } else {
                            fileName = 'excel.pdf'
                        }

                        try {
                            let objectUrl1 = window.URL.createObjectURL(new Blob([res.data]));
                            let elink = document.createElement('a');
                            elink.setAttribute('download', decodeURI(decodeURI(fileName)));
                            elink.style.display = 'none';
                            elink.href = objectUrl1;
                            document.body.appendChild(elink);
                            elink.click();
                            document.body.removeChild(elink);
                            window.URL.revokeObjectURL(elink.href);
                        }catch (err){
                            this.$message.warning('download error!')
                        }
                    }
                )

后端的respon返回,同时需要加个返回头

response.setHeader("Access-Control-Expose-Headers", "content-disposition");
    @PostMapping("/pdf")
    public void getPdfAndDownload(@RequestBody SateiTable sateiTable, HttpServletResponse response) throws IOException {
      
        // 生成PDF   略
          

        //下载PDF
        try {
            // path是指想要下载的文件的路径
            File file = new File(filepdfpath + pdfName);

            System.out.println("文件路径: " + file.getPath());
            // 获取文件名
            String filename = file.getName();
            System.out.println("文件名: " + filename);
            // 获取文件后缀名
            String ext = filename.substring(filename.lastIndexOf(".")).toLowerCase();
            System.out.println("文件后缀名:" + ext);
            // path是指想要下载的文件的路径

            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            // 设置文件下载头
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(pdfName, "UTF-8"));
            // 设置文件长度
            response.setHeader("Content-Length", String.valueOf(file.length()));
            //
            response.setHeader("Access-Control-Expose-Headers", "content-disposition");
            //获取响应报文输出流对象
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            //设置响应内容类型
            response.setContentType("application/octet-stream");
            //输出
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

结果展示 

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值