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

Jetty 11配置CORS Filter遇跨域错误:响应头多值冲突

解决Jetty 11.0.14 CORS Filter配置重复头问题

问题根源

你遇到的Access-Control-Allow-Origin头包含多个值的错误,是因为同时启用了Jetty官方的CrossOriginFilter和在Servlet中手动添加CORS响应头,两者都向响应中写入了相同的CORS头,导致浏览器检测到重复值而报错。

修复步骤

  1. 移除Servlet中手动添加的CORS头
    删掉Nothing类doGet方法里所有和CORS相关的res.addHeader()调用,让CrossOriginFilter全权处理跨域逻辑。

  2. 优化Filter配置(可选但推荐)
    可以补充几个常用的CORS配置参数,比如允许携带凭证、设置预检请求缓存时长,让配置更完整。

修改后的完整代码

import org.eclipse.jetty.util.thread.*;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.servlet.*;
import org.eclipse.jetty.servlets.*;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.*;

public class WebServerUtil {
    public static void main(String[] args) {
        try {
            // setup server
            QueuedThreadPool threadPool = new QueuedThreadPool();
            threadPool.setName("server");
            Server server = new Server(threadPool);

            // setup server connections
            HttpConfiguration config = new HttpConfiguration();
            HttpConnectionFactory httpConnection = new HttpConnectionFactory(config);
            ServerConnector connector = new ServerConnector(server, httpConnection);
            connector.setHost("0.0.0.0");
            connector.setPort(8080);
            server.setConnectors(new Connector[] { connector });

            // setup handler
            ServletHandler handler = new ServletHandler();
            server.setHandler(handler);

            // setup cors
            FilterHolder filter = new FilterHolder(CrossOriginFilter.class);
            filter.setName("CORS");
            filter.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
            filter.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "*");
            filter.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "POST, GET, OPTIONS");
            // 可选:允许携带Cookie等凭证
            filter.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true");
            // 可选:设置预检请求缓存时长(秒)
            filter.setInitParameter(CrossOriginFilter.PREFLIGHT_MAX_AGE_PARAM, "3600");
            FilterMapping mapping = new FilterMapping();
            mapping.setFilterName("CORS");
            mapping.setPathSpecs(new String[]{"/*"});
            mapping.setDispatches(FilterMapping.ALL);
            handler.addFilter(filter, mapping);

            // basic route
            ServletHolder nothing = new ServletHolder(new Nothing());
            handler.addServletWithMapping(nothing, "/");

            // start server
            server.start();
            server.join();
        } catch(Exception error) {
            System.out.println(error.getMessage());
        }
    }
}

class Nothing extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        res.setStatus(200);
        res.addHeader("Content-Type", "application/json");
        res.getWriter().println("{\"message\":\"Nothing\"}");
    }
}

额外说明

  • Jetty的CrossOriginFilter会自动处理预检OPTIONS请求,不需要你在Servlet中手动处理,它会返回符合规范的响应头。
  • 如果需要针对特定路径或Origin做更精细的控制,可以修改ALLOWED_ORIGINS_PARAM的值,比如指定具体域名列表(用逗号分隔),而不是通配符*。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 19:15:11