关于传统的JavaWeb(Servlet+Mybatis)项目部署Tomcat后的跨域问题解决方案

关于传统的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;
        }