赞
踩
在本地调试时,点击导出提示
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);
}
}
解决方案
在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); }
现在又遇到了新的问题,前端下载组件获取流后,无法获取文件名称。
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) }
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); } }
返回结果 headers 中存在 content-disposition 值
Access-Control-Allow-Origin 用于设置允许跨域请求源地址 (预检请求和正式请求在跨域时候都会验证)
Access-Control-Allow-Headers 跨域允许携带的特殊头信息字段 (只在预检请求验证)
Access-Control-Allow-Methods 跨域允许的请求方法或者说HTTP动词 (只在预检请求验证)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。