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

Tomcat 9下JAX-RS服务Ajax POST请求跨域报错求助

Ah, classic CORS gotcha! Postman works because it skips sending the preflight OPTIONS request that browsers automatically trigger for cross-origin requests (especially POST requests with custom headers or content types). Let's walk through the most reliable fixes for your JAX-RS + Tomcat 9 setup:

1. Implement a JAX-RS CORS Response Filter

This is a code-level fix that gives you fine-grained control over CORS rules for your API. Create a filter class that adds the required headers to every response:

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Provider
public class CorsFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        // Replace "*" with your frontend's actual domain in production (e.g., "https://your-app.com")
        responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
        responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
        responseContext.getHeaders().add("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization");
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    }
}

Next, make sure this filter is registered with your JAX-RS application:

  • If you're using a ResourceConfig class, add register(CorsFilter.class) to its constructor.
  • If you're configuring via web.xml, add the filter's fully qualified class name to the <init-param> of your JAX-RS servlet under javax.ws.rs.Application or jersey.config.server.provider.classnames.

You'll also need to handle OPTIONS preflight requests (browsers send these before the actual POST). Add a generic OPTIONS endpoint to catch all such requests:

import javax.ws.rs.OPTIONS;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

@Path("/")
public class CorsOptionsHandler {

    @OPTIONS
    @Path("{path:.*}")
    public Response handleOptionsRequests() {
        return Response.ok().build();
    }
}
2. Configure Global CORS in Tomcat

If you don't want to modify your API code, you can enable CORS globally for all apps on your Tomcat server. Edit conf/web.xml (in your Tomcat installation directory) and add these entries:

<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> <!-- Replace with your frontend domain in production -->
  </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>Origin, Content-Type, Accept, Authorization</param-value>
  </init-param>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Restart Tomcat after making this change, and all your applications will automatically handle CORS preflight requests.

3. Use Your JAX-RS Framework's Built-in CORS Support

If you're using a specific JAX-RS implementation like Jersey, it has built-in CORS support you can leverage. For Jersey:

Register the CorsFilter in your ResourceConfig:

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.filter.CorsFilter;

public class MyApiApplication extends ResourceConfig {
    public MyApiApplication() {
        register(CorsFilter.class);
        // Register your API resources here
    }
}

Then configure CORS rules via web.xml init params:

<servlet>
  <servlet-name>MyApi</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>com.yourpackage.MyApiApplication</param-value>
  </init-param>
  <init-param>
    <param-name>jersey.config.server.cors.allowedOrigins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>jersey.config.server.cors.allowedMethods</param-name>
    <param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
  </init-param>
</servlet>

Important Notes for Production

  • Never use * for Access-Control-Allow-Origin in production. Replace it with your frontend's exact domain (e.g., https://your-frontend.com).
  • If your frontend sends credentials (like cookies), Access-Control-Allow-Origin must be a specific domain (not *), and Access-Control-Allow-Credentials must be set to true.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:18:49