本文主要是介绍Java 文件下载名称为空问题解决 Access-Control-Expose-Headers,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 1. 问题背景
- 2. 根因
- 3. 解决方法
1. 问题背景
日常实现下载文件的需求,前端代码从 HTTP 响应的响应头 Content-Disposition
中获取文件名称,但获取到的是空字符串。后端在 Spring 框架中使用以下代码确实设置了 Content-Disposition
响应头,从浏览器的 Network 里也能看到 Content-Disposition
响应头的确存在,然而前端就是获取不到值
@SneakyThrowspublic static ResponseEntity<ByteArrayResource> downloadResponse(String outputFilename, byte[] bytes) {if (StringUtils.isEmpty(outputFilename)) {outputFilename = "file";}outputFilename = URLEncoder.encode(outputFilename, StandardCharsets.UTF_8.name());return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + outputFilename).header(HttpHeaders.ACCEPT_RANGES, "bytes").header(HttpHeaders.PRAGMA, "No-cache").header(HttpHeaders.CACHE_CONTROL, "No-cache").header(HttpHeaders.EXPIRES, "0").body(new ByteArrayResource(bytes));}
2. 根因
之所以会产生这种情况,是因为浏览器的安全功能限制。默认情况下,HTTP 协议只有以下 7 种 简单响应头(simple response headers)
可以暴露给外部客户端访问,这 7 种响应头既可以在浏览器 Network 里看到,也能在 JS 代码里获取。上文中虽然服务端在 HTTP 响应里加了 Content-Disposition
响应头,但是因为这个响应头默认不能暴露给外部,所以浏览器会限制客户端 JS 代码读取该响应头的值,最终造成前端读取到空值
Cache-Control、Content-Language、Content-Length、Content-Type、Expires、Last-Modified、Pragma
3. 解决方法
事实上,HTTP 协议的响应头 Access-Control-Expose-Headers
可以配置哪些响应头能够被外部客户端访问。所以想要让客户端可以访问到其他的响应头信息,服务端不仅要在 HTTP 响应里加入该响应头,还要通过额外的响应头 Access-Control-Expose-Headers
声明其可以被外部访问。经过改动,最终生成可下载文件的 HTTP 响应的代码如下,这样前端就能够获取到 Content-Disposition
的值了
@SneakyThrowspublic static ResponseEntity<ByteArrayResource> downloadResponse(String outputFilename, byte[] bytes) {if (StringUtils.isEmpty(outputFilename)) {outputFilename = "file";}outputFilename = URLEncoder.encode(outputFilename, StandardCharsets.UTF_8.name());return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + outputFilename).header(HttpHeaders.ACCEPT_RANGES, "bytes").header(HttpHeaders.PRAGMA, "No-cache").header(HttpHeaders.CACHE_CONTROL, "No-cache").header(HttpHeaders.EXPIRES, "0").header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION).body(new ByteArrayResource(bytes));}
这篇关于Java 文件下载名称为空问题解决 Access-Control-Expose-Headers的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!