Angular 11中GET重定向请求报错net::ERR_UNSAFE_REDIRECT 302求助
解决Angular 11订阅Spring受保护GET接口时的ERR_UNSAFE_REDIRECT问题
第一步:修正Spring接口的响应逻辑
你的Spring接口必须返回200 OK状态码,而非302重定向。如果接口意外触发了重定向(比如用了redirect:前缀或sendRedirect()方法),浏览器会直接处理重定向,但目标URL未携带JWT令牌,就会触发ERR_UNSAFE_REDIRECT错误。
修改后的Spring接口示例:
@GetMapping("/generate-url") public ResponseEntity<Void> generateUrl(HttpServletRequest request) { // 生成目标URL的逻辑 String generatedUrl = buildTargetUrl(request); HttpHeaders headers = new HttpHeaders(); // 用自定义响应头传递生成的URL headers.add("X-Generated-Url", generatedUrl); return new ResponseEntity<>(headers, HttpStatus.OK); }
第二步:配置Spring允许暴露自定义响应头
Angular默认无法获取非标准响应头,需要在Spring端配置CORS,允许暴露自定义头:
- 局部配置(针对单个接口):
@CrossOrigin(exposedHeaders = "X-Generated-Url") @GetMapping("/generate-url") public ResponseEntity<Void> generateUrl(HttpServletRequest request) { // 逻辑同上 }
- 全局CORS配置:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("你的Angular应用域名") .allowedMethods("GET", "POST", "PUT", "DELETE") .exposedHeaders("X-Generated-Url"); } }
第三步:Angular端正确读取响应头并处理
在Angular服务中订阅接口时,需要指定observe: 'response'才能获取完整响应头,示例代码:
import { HttpClient } from '@angular/common/http'; import { Observable, map } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class UrlGeneratorService { constructor(private http: HttpClient) {} getGeneratedUrl(): Observable<string> { return this.http.get('/api/generate-url', { observe: 'response', responseType: 'text' }) .pipe( map(response => { const targetUrl = response.headers.get('X-Generated-Url'); if (!targetUrl) throw new Error('响应头未包含生成的URL'); return targetUrl; }) ); } }
第四步:处理目标URL的跳转(携带JWT令牌)
由于目标URL受保护,不能直接用window.open()跳转,可通过两种方式处理:
- 方式一:通过Angular的HttpClient请求目标URL,再处理响应(如下载文件):
this.urlGeneratorService.getGeneratedUrl().subscribe(targetUrl => { this.http.get(targetUrl, { responseType: 'blob' }).subscribe(blob => { const blobUrl = window.URL.createObjectURL(blob); window.open(blobUrl); }); });
- 方式二:若目标接口支持令牌作为查询参数,手动拼接后跳转:
this.urlGeneratorService.getGeneratedUrl().subscribe(baseUrl => { const jwtToken = localStorage.getItem('auth-token'); const fullUrl = `${baseUrl}?token=${jwtToken}`; window.open(fullUrl, '_blank'); });
内容的提问来源于stack exchange,提问作者Alexander Mladzhov
相关产品推荐
相关产品推荐

