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

Java中为WebSocket握手响应添加CORS头部的实现方案

WebSocket跨域CORS问题解决方案(Tyrus服务器)

问题背景

浏览器端JS应用连接基于Tyrus运行的WebSocket服务时,出现GET has been blocked by CORS policy错误。现有启动代码如下:

public static void main(String[] args) {
        int port = Integer.parseInt(args[0]);

        final Server server = new Server("0.0.0.0", port, "/", null, LiveWebSocket.class);
        try {
            server.start();
            System.out.println("WebSocketServer started on port " + port);
        } catch (final DeploymentException e) {
            throw new RuntimeException("Failed to start WebSocketServer", e);
        }

        try {
            Thread.currentThread().join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

已实现CORS过滤器并注册到ResourceConfig,但不知道如何将配置集成到main方法的服务器启动流程中:

@Provider
public class CorsFilter implements ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
        responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
        responseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
        responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        responseContext.getHeaders().add("Access-Control-Max-Age", "1209600");
    }
}
final ResourceConfig config = new ResourceConfig();
config.register(CorsFilter.class);
config.register(LiveWebSocket.class);

解决方案

方案1:通过ServerConfig集成ResourceConfig

Tyrus的Server类支持传入ServerConfig对象加载自定义配置,只需修改main方法的服务器初始化逻辑:

public static void main(String[] args) {
    int port = Integer.parseInt(args[0]);

    // 初始化配置并注册过滤器与WebSocket端点
    final ResourceConfig config = new ResourceConfig();
    config.register(CorsFilter.class);
    config.register(LiveWebSocket.class);

    // 将ResourceConfig转换为ServerConfig
    final ServerConfig serverConfig = ServerConfig.Builder.create().resourceConfig(config).build();

    // 使用带ServerConfig的构造函数创建服务器
    final Server server = new Server("0.0.0.0", port, "/", serverConfig);
    try {
        server.start();
        System.out.println("WebSocketServer started on port " + port);
    } catch (final DeploymentException e) {
        throw new RuntimeException("Failed to start WebSocketServer", e);
    }

    try {
        Thread.currentThread().join();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
}

此方法会让CORS过滤器作用于所有HTTP请求(包括WebSocket握手请求),解决跨域问题。

方案2:直接添加WebSocket握手拦截器

如果方案1不生效,可以直接针对WebSocket握手阶段添加拦截器,更精准处理跨域:

  1. 实现握手拦截器:
import java.util.Collections;
import javax.websocket.HandshakeRequest;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.ServerEndpointConfig;

public class CorsHandshakeInterceptor implements ServerEndpointConfig.Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        response.getHeaders().put("Access-Control-Allow-Origin", Collections.singletonList("*"));
        response.getHeaders().put("Access-Control-Allow-Credentials", Collections.singletonList("true"));
        // 按需添加其他CORS头部,如Access-Control-Allow-Headers等
    }
}
  1. 在WebSocket端点类上配置该拦截器:
import javax.websocket.ServerEndpoint;

@ServerEndpoint(value = "/your-websocket-path", configurator = CorsHandshakeInterceptor.class)
public class LiveWebSocket {
    // 你的WebSocket业务逻辑
}

这种方式直接修改握手响应头,确保跨域规则被应用到WebSocket连接的初始请求上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:45:14