当前位置:   article > 正文

has been blocked by CORS policy: No ‘Access-Control-Allow-Origin‘ header is present on the requested_has been blocked by cors policy: no 'access-contro

has been blocked by cors policy: no 'access-control-allow-origin' header is

在本地调试时,点击导出提示
has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

在这里插入图片描述

原始代码;

public static void exportTemplate(String excelName, Workbook workbook) {
        try {
            HttpServletResponse response = HttpServletUtil.getResponse();
            String fileName = URLEncoder.encode(excelName, "UTF-8");
            response.reset();
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
            response.setContentType("application/octet-stream;charset=UTF-8");
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception exception) {
            log.error(">>> 导出数据异常:{}", exception);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

解决方案
在response.reset(); 后面添加两个行代码,可以解决前端跨域问题。

 public static void exportTemplate(String excelName, Workbook workbook) {
        try {
            HttpServletResponse response = HttpServletUtil.getResponse();
            String fileName = URLEncoder.encode(excelName, "UTF-8");
            response.reset();
            // 解决前端跨域
            response.addHeader("Access-Control-Allow-Origin", "*");
            //response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type");
            
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
            response.setContentType("application/octet-stream;charset=UTF-8");
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception exception) {
            log.error(">>> 导出数据异常:{}", exception);
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

现在又遇到了新的问题,前端下载组件获取流后,无法获取文件名称。

var contentDisposition = res.headers[‘content-disposition’] 获取不到文件信息。
后端添加的 response.setHeader(“Content-Disposition”, “attachment; filename=”" + fileName + “”"); 没有添加成功。

前端流下载组件

 downloadfile (res) {
      this.batchExportLoading = false
      var blob = new Blob([res.data], { type: 'application/octet-stream;charset=UTF-8' })
      var contentDisposition = res.headers['content-disposition']
      var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
      var result = patt.exec(contentDisposition)
      var filename = result[1]
      var downloadElement = document.createElement('a')
      var href = window.URL.createObjectURL(blob) // 创建下载的链接
      var reg = /^["](.*)["]$/g
      downloadElement.style.display = 'none'
      downloadElement.href = href
      downloadElement.download = decodeURI(filename.replace(reg, '$1')) // 下载后文件名
      document.body.appendChild(downloadElement)
      downloadElement.click() // 点击下载
      document.body.removeChild(downloadElement) // 下载完成移除元素
      window.URL.revokeObjectURL(href)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

debug信息
在这里插入图片描述
返回结果打印信息
里面没有 content-disposition 信息。

解决方案:
后端添加 response.setHeader(“Access-Control-Expose-Headers”, “Content-Disposition”);

在使用CORS方式跨域时,浏览器只会返回 默认的头部 Header。
在后端响应信息中添加 Access-Control-Expose-Headers 响应报头,指可以公开的报头信息。

    public static void exportTemplate(String excelName, Workbook workbook) {
        try {
            HttpServletResponse response = HttpServletUtil.getResponse();
            String fileName = URLEncoder.encode(excelName, "UTF-8");
            response.reset();
            // 解决前端跨域
            response.addHeader("Access-Control-Allow-Origin", "*");
            //response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type");
            
            // 需要添加以下配置 否则前获取不到 Content-Disposition
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
            response.setContentType("application/octet-stream;charset=UTF-8");
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception exception) {
            log.error(">>> 导出数据异常:{}", exception);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

返回结果 headers 中存在 content-disposition 值
在这里插入图片描述

Access-Control-Allow-Origin 用于设置允许跨域请求源地址 (预检请求和正式请求在跨域时候都会验证)
Access-Control-Allow-Headers 跨域允许携带的特殊头信息字段 (只在预检请求验证)
Access-Control-Allow-Methods 跨域允许的请求方法或者说HTTP动词 (只在预检请求验证)

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/344771
推荐阅读
相关标签
  

闽ICP备14008679号