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
相关产品推荐
相关产品推荐

