You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 12:20:54