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

Angular interceptor调用非公开接口报strict-origin-when-cross-origin错误如何解决

问题根因拆解

你遇到的两次请求是浏览器CORS机制触发的OPTIONS预检请求,核心问题出在后端CORS和Spring Security的配置错误,而非Angular拦截器的问题:

  • 当跨域请求携带自定义头(如Authorization)时,浏览器会自动发起OPTIONS预检请求,确认后端允许该跨域请求后才会发送真实业务请求
  • 你完全关闭了Spring的CORS支持,导致后端无法正常响应OPTIONS预检请求,预检直接失败,浏览器就会阻断后续的真实业务请求,所以你会看到第二次请求未触达后端
  • 公开接口未触发该问题,要么是公开接口的请求刚好符合简单请求规则无需预检,要么是你配置了公开路径放行所有请求包括OPTIONS

解决步骤

1. 后端正确配置CORS(不要完全关闭CORS支持)

完全关闭CORS的方案不适用跨域带自定义头的场景,改用如下配置:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                // 替换为你的前端实际访问地址,带凭证场景不允许使用*
                .allowedOrigins("http://localhost:4200")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                // 预检请求缓存1小时,有效期内无需重复发起预检
                .maxAge(3600);
    }
}

2. Spring Security放行OPTIONS请求

OPTIONS请求不会携带Authorization头,会被非公开路径的鉴权规则拦截,需要单独放行:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
            .and()
            .authorizeRequests()
            // 放行所有OPTIONS请求
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers("/api/public/**").permitAll()
            .anyRequest().authenticated();
        // 其余你的鉴权配置保持不变
    }
}

3. 优化Angular拦截器逻辑(可选,规避不必要的问题)

避免给OPTIONS请求加Authorization头,同时补全Bearer前缀(绝大多数后端鉴权逻辑要求该格式):

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<unknown>> {
  // OPTIONS请求直接跳过加头
  if (req.method === 'OPTIONS') {
    return next.handle(req);
  }
  const token = this.getAccessToken();
  if (token) {
    const authReq = req.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`
      }
    });
    return next.handle(authReq);
  }
  return next.handle(req);
}

配置完成后重新测试即可看到OPTIONS请求返回200状态,后续真实请求会正常携带Authorization头访问非公开接口。


内容的提问来源于stack exchange,提问作者bosznorbi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:36:02