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

Tomcat配置CORS后仍遇跨域拦截,OPTIONS请求返回403求助

问题

跨域调用Tomcat后端服务时触发CORS错误,React前端收到如下提示:

Access to fetch at 'https://tomcat:8443/post/service ' from origin 'https://domainReact:8443/react' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

后端Tomcat 9配置(conf/web.xml)

<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.support.credentials</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>cors.request.decorate</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>cors.allowed.methods</param-name>
            <param-value>GET,POST,DELETE,OPTIONS,PUT</param-value>
        </init-param>

        <init-param>
            <param-name>cors.allowed.headers</param-name>
            <param-value>Content-Type,X-Requested-With,Access-Control-Request-Method,Access-Control-Request-Headers,accept,Origin,Access-Control-Allows-Origin,alias,Authorization,customerId</param-value>
        </init-param>

        <init-param>
            <param-name>cors.exposed.headers</param-name>
            <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Access-Control-Request-Headers</param-value>
        </init-param>
        <init-param>
            <param-name>cors.preflight.maxage</param-name>
            <param-value>1728000</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CorsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>CSRF</filter-name>
        <filter-class>org.apache.catalina.filters.CsrfPreventionFilter</filter-class>
        <init-param>
            <param-name>entryPoints</param-name>
            <param-value>/html,/html/</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>httpHeaderSecurity</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    <filter-mapping>
        <filter-name>CSRF</filter-name>
        <servlet-name>servlet</servlet-name>
    </filter-mapping>

网络请求详情

请求信息

General:
Request URL: https://tomcat:8443/post/service
Request Method: OPTIONS
Status Code: 403 
Remote Address: 172.16.0.233:8443
Referrer Policy: strict-origin-when-cross-origin

Request Headers:
:authority: https://tomcat:8443
:method: OPTIONS
:path: /post/service
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
access-control-request-headers: alias,authorization,content-type,customerid
access-control-request-method: POST
access-control-request-private-network: true
origin: https://domainReact:8443/react
referer: https://domainReact:8443/react/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site

响应信息

Response Headers:
cache-control: private
content-length: 683
content-type: text/html;charset=utf-8

补充说明

  • 使用alias、customerId两个自定义请求头,API通过JAX-RS暴露,未配置额外CORS过滤器
  • 移除Tomcat的CorsFilter后错误依旧
  • Java调用服务正常,仅React/JavaScript调用出现问题
  • 已将自定义头添加到Tomcat过滤器配置,但响应中看不到CORS相关头信息

解决分析与方案

核心问题:CSRF过滤器拦截了OPTIONS预检请求

从403状态码和配置顺序来看,CsrfPreventionFilter是导致预检请求失败的关键:

  • 跨域预检的OPTIONS请求不在CSRF过滤器的entryPoints列表中,被判定为非法请求直接返回403
  • 由于过滤器映射顺序由配置顺序决定,CSRF过滤器在CorsFilter之前执行,OPTIONS请求还没到CorsFilter就被拦截

修复步骤

  1. 更新CSRF过滤器的entryPoints参数,将OPTIONS请求或目标接口路径加入允许列表:

    <filter>
        <filter-name>CSRF</filter-name>
        <filter-class>org.apache.catalina.filters.CsrfPreventionFilter</filter-class>
        <init-param>
            <param-name>entryPoints</param-name>
            <!-- 方式1:添加目标接口路径 -->
            <param-value>/html,/html/,/post/service</param-value>
            <!-- 方式2:直接允许所有OPTIONS请求 -->
            <!-- <param-value>/html,/html/,OPTIONS</param-value> -->
        </init-param>
    </filter>
    
  2. 调整过滤器执行顺序,确保CorsFilter在CsrfPreventionFilter之前处理请求:
    在web.xml中把CorsFilter的配置和映射代码段,移到CSRF过滤器的配置前面,让预检请求先被CorsFilter处理并返回合法响应。

  3. 统一自定义请求头的大小写:
    配置中cors.allowed.headers是customerId,但请求头里是全小写的customerid,虽然HTTP头不区分大小写,但部分框架可能存在严格匹配问题,建议统一为小写或保持一致。

  4. 验证CORS过滤器生效状态:
    确认Tomcat 9自带的CorsFilter依赖正常,且过滤器的url-pattern(当前为/*)覆盖了所有需要跨域的接口路径。

额外验证

  • 测试前清空浏览器缓存,避免旧的错误响应干扰
  • 查看Tomcat日志,确认OPTIONS请求是否被CSRF过滤器拦截的记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:02:20