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

Ngrok环境下Angular+SpringBoot的CORS异常:POST正常GET请求失败

Ngrok跨域问题:POST正常但GET请求失败(刷新前端后触发CORS错误)

问题场景

  • 用两个免费Ngrok地址分别映射本地Angular服务(localhost:4200)和SpringBoot后端服务(localhost:8080)
  • 前端通过Ngrok后端地址发起请求时,POST请求正常,GET请求触发CORS错误
  • 直接访问Ngrok后端地址无异常
  • 首次请求一切正常,刷新前端后出现问题

当前使用的CORS过滤器代码

@Component
public class CorsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "7200");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Authorization, Content-Type, xsrf-token, X-Requested-With, Accept, X-Auth-Token");
        response.addHeader("Access-Control-Expose-Headers", "xsrf-token");

        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            filterChain.doFilter(request, response);
        }
    }
}

解决方案

  1. 修正Origin配置(针对带凭证的请求)
    如果你的Angular请求携带了Cookie、认证令牌等凭证(withCredentials: true),Access-Control-Allow-Origin不能设为*,需要动态获取请求的Origin并返回:
String origin = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Credentials", "true");
  1. 提升过滤器优先级
    确保CORS过滤器最先执行,避免其他过滤器(如Spring Security)提前拦截请求导致跨域头未正确设置。添加@Order注解:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter extends OncePerRequestFilter {
    // 原有代码...
}
  1. 排查浏览器预检缓存
    Access-Control-Max-Age: 7200会让浏览器缓存OPTIONS预检请求结果2小时,若期间Ngrok域名变化(免费版可能重启后变更),会导致缓存不匹配。可临时将Max-Age设为0,或清除浏览器缓存测试。

  2. 改用Spring Boot官方CORS配置
    替换自定义过滤器,使用Spring MVC提供的全局CORS配置,兼容性更好:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*") // 若带凭证,替换为你的Ngrok前端地址
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("Origin", "Authorization", "Content-Type", "xsrf-token", "X-Requested-With", "Accept", "X-Auth-Token")
                .exposedHeaders("xsrf-token")
                .allowCredentials(true) // 需携带凭证时开启
                .maxAge(7200);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:10:49