关于传统的JavaWeb(Servlet+Mybatis)项目部署Tomcat后的跨域问题解决方案
时过境迁,因为某些不可预知的原因,我遇到了这个问题,如果是以前用spring 框架写的后端,直接在请求方法名上加@CrossOrgin 就解决了。
总结的方案:
- Tomcat 全局化配置跨域
- 针对具体的JavaWeb项目配置跨域
冲突点:
Tomcat全局化配置
和JavaWeb配置
会冲突,存在重复配置的问题
的问题。
- 如果设置了过滤器则需要正确处理预检请求,遇到
options
方法直接放行。
相应配置如下
| JAVAWEB 配置 |
在登录校验的过滤器中设置
响应体的请求头
cpp
// 请求头设置允许跨域
// httpResponse.setHeader("Access-Control-Allow-Origin", "*");
httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,HEAD,OPTIONS,PUT");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Headers",
"Content-Type,X-Requested-With,accept,Origin,Range,Access-Control-Request-Method,Access-Control-Request-Headers");
httpResponse.setHeader("Access-Control-Expose-Headers", "Accept-Ranges, Content-Encoding, Content-Length, Content-Range");
其中 supportsCredentials = true
的响应体的请求头会与allowedOrigins=*
冲突。
报错日志如下:
cpp
八月 22, 2025 12:02:30 上午 org.apache.catalina.core.StandardContext filterStart
严重: 启动过滤器异常
javax.servlet.ServletException: It is not allowed to configure supportsCredentials=[true] when allowedOrigins=[*]
at org.apache.catalina.filters.CorsFilter.parseAndStore(CorsFilter.java:779)
at org.apache.catalina.filters.CorsFilter.init(CorsFilter.java:190)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:285)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:266)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:5037)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5739)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1705)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1695)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Tomcat 配置
cpp
<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>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>1000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
值得注意的Tomcat配置的某些选项会与JavaWeb配置的冲突
如JAVAWEB项目中过滤器
filter
中的httpResponse.setHeader("Access-Control-Allow-Origin", "*");
与Tomcat的web.xml的<init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param>
会冲突.
正确处理预检请求(在设置过滤器的情况下)
cpp
if ("OPTIONS".equalsIgnoreCase(httpRequest.getMethod())) {
System.out.println("[预检]");
httpResponse.setStatus(HttpServletResponse.SC_OK);
return;
}