Spring设置自定义响应头UID,Angular前端获取时值为null
问题原因
跨域场景下浏览器默认做了响应头访问限制,前端JS只能读取6个默认的安全响应头,自定义响应头如果没有被后端显式标记为可暴露,哪怕请求实际返回了该头、你能在浏览器开发者工具的Network面板看到它,JS代码调用接口读取时也只会拿到null。
默认允许JS读取的响应头只有:
- Cache-Control
- Content-Language
- Content-Type
- Expires
- Last-Modified
- Pragma
你自定义的UID不在这个列表里,所以读取失败。
修复方案
1. 后端配置暴露自定义响应头
核心是给响应加上Access-Control-Expose-Headers头,把UID加入允许前端读取的列表,两种配置方式选一个就行:
- 单接口配置:直接在你现有的ResponseEntity构造逻辑里加一行头配置
return ResponseEntity.ok() .contentType(MediaType.parseMediaType("application/octet-stream")) .header("Content-Disposition", "filename=" + fileName) .header("Accept-Ranges", "bytes") // 新增该行,声明UID头允许前端JS读取 .header("Access-Control-Expose-Headers", "UID") .header("UID","ug2781") .body(content);
- 全局CORS配置:如果项目里有统一的跨域配置,直接在全局规则里加暴露配置,避免每个接口单独写
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") // 全局暴露自定义响应头,多个自定义头用逗号分隔 .exposedHeaders("UID") .allowCredentials(true) .maxAge(3600); } }
2. 清理前端无效配置
你当前前端代码里在请求头里加Access-Control-Allow-Origin: *是完全无效的,这个头是后端返回给浏览器的跨域校验标识,前端主动携带没有任何作用,直接删掉即可。
修正后的Angular请求代码:
getFile(url:string, uid:any):Observable<any>{ const reqHeaders = new HttpHeaders({ 'UID': uid }); return this.http.get(`${urls.fileurl}?url=${url}`, { headers: reqHeaders, responseType: 'arraybuffer' as 'json', observe: 'response' }) .pipe( map(res => res), catchError(err => { console.log(err); return throwError(() => err); }) ); }
验证方法
重启后端服务后重新发起请求,在浏览器Network面板查看对应接口的响应头,能看到Access-Control-Expose-Headers: UID字段时,前端res.headers.get("UID")就能正常读取到ug2781的值。
注意:HttpHeaders的get方法对响应头字段名大小写不敏感,写
uid/Uid/UID都能正常匹配,不需要刻意调整字段大小写。
内容的提问来源于stack exchange,提问作者Vikash Mishra
相关产品推荐
相关产品推荐

