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

Tomcat+SpringMVC+AngularJS环境下CORS预检请求403错误求助

兄弟,你这是典型的跨域预检请求被Tomcat拒绝的问题啊!我之前在SpringMVC+AngularJS的项目里也踩过这个坑,给你几个靠谱的解决办法,按需选就行:

方法一:自定义SpringMVC CORS过滤器(全局生效)

这是最通用的方案,直接写个过滤器处理所有跨域相关请求,包括浏览器自动发送的OPTIONS预检请求:

先创建一个过滤器类:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CorsFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        HttpServletRequest req = (HttpServletRequest) request;
        
        // 替换成你的前端实际域名,生产环境别用*(不安全)
        res.setHeader("Access-Control-Allow-Origin", "http://你的前端地址");
        // 允许的请求方法,一定要包含OPTIONS
        res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        // 允许的请求头,根据你的实际需求调整
        res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        // 预检请求的缓存时间,减少重复请求
        res.setHeader("Access-Control-Max-Age", "3600");
        
        // 如果是OPTIONS预检请求,直接返回200状态码,不用走后续业务逻辑
        if ("OPTIONS".equalsIgnoreCase(req.getMethod())) {
            res.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {}
}

然后在web.xml里配置这个过滤器,注意要放在所有过滤器的最前面,避免被其他拦截器先处理:

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>com.你的包名.CorsFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

方法二:用Spring自带的@CrossOrigin注解(局部生效)

如果只是个别接口需要跨域支持,直接在Controller或者具体方法上加注解就行,简单快捷(要求Spring版本4.2+):

@RestController
@RequestMapping("/navbar")
// 针对整个Controller配置跨域
@CrossOrigin(origins = "http://你的前端地址", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.OPTIONS})
public class NavbarController {
    @GetMapping("/getnavbartxt")
    // 也可以单独给这个方法配置
    // @CrossOrigin(origins = "http://你的前端地址")
    public ResponseEntity<?> getNavbarTxt() {
        // 你的业务逻辑代码
        return ResponseEntity.ok(你的JSON数据);
    }
}

方法三:直接配置Tomcat全局跨域(不用改业务代码)

如果不想动项目代码,可以直接修改Tomcat的conf/web.xml,添加官方自带的CORS过滤器:

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>http://你的前端地址</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Content-Type,Authorization</param-value>
    </init-param>
    <init-param>
        <param-name>cors.preflight.maxage</param-name>
        <param-value>3600</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

修改完记得重启Tomcat才能生效。

几个关键注意点:

  • 生产环境绝对不要用*允许所有源,一定要指定具体的前端域名,防止跨域安全漏洞。
  • 浏览器的OPTIONS预检请求是自动触发的,你不用在AngularJS代码里手动发送,只要后端能正确响应就行。
  • 检查项目里的其他过滤器/拦截器,比如权限拦截器,别把OPTIONS请求给拦了,要让它先过CORS过滤器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:07:03