Jetty 11配置CORS Filter遇跨域错误:响应头多值冲突
解决Jetty 11.0.14 CORS Filter配置重复头问题
问题根源
你遇到的Access-Control-Allow-Origin头包含多个值的错误,是因为同时启用了Jetty官方的CrossOriginFilter和在Servlet中手动添加CORS响应头,两者都向响应中写入了相同的CORS头,导致浏览器检测到重复值而报错。
修复步骤
移除Servlet中手动添加的CORS头
删掉Nothing类doGet方法里所有和CORS相关的res.addHeader()调用,让CrossOriginFilter全权处理跨域逻辑。优化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
相关产品推荐
相关产品推荐

