
Micronaut 默认拒绝跨域 WebSocket 连接,需通过 server.cors.configurations 显式配置允许的前端源(如 http://dev.domain.com:8080),仅启用全局 CORS(cors.enabled=true)不足以生效。
micronaut 默认拒绝跨域 websocket 连接,需通过 `server.cors.configurations` 显式配置允许的前端源(如 `http://dev.domain.com:8080`),仅启用全局 cors(`cors.enabled=true`)不足以生效。
在 Micronaut 中启用跨域 WebSocket(WebSocket over HTTP Upgrade)连接,关键在于理解其 CORS 机制与传统 HTTP 请求的差异:WebSocket 握手本质上是带特殊头部(Upgrade: websocket, Connection: Upgrade)的 HTTP GET 请求,Micronaut 的 CORS 配置必须明确覆盖该路径与来源,否则会直接返回 403 Forbidden(如 Firefox 所示),且请求甚至不会抵达你的 @ServerWebSocket 类——这也解释了为何服务日志中无访问痕迹。
Micronaut 的 server.cors.enabled=true 仅启用 CORS 支持框架,但不自动放行任何源;真正控制白名单的是 server.cors.configurations 下的具名配置项(如 ui),它会匹配 WebSocket 升级请求的 Origin 头。正确配置如下(application.yml):
micronaut:
application:
name: application-name
server:
port: 8081
cors:
enabled: true
configurations:
ui: # 配置名称(任意,但需唯一)
allowed-origins: "http://dev.domain.com:8080" # ✅ 必须精确匹配前端 Origin
allowed-methods: "GET,HEAD"
allowed-headers: "Sec-WebSocket-Key, Sec-WebSocket-Version, Sec-WebSocket-Extensions, Connection, Upgrade"
exposed-headers: "X-Example-Header"
allow-credentials: true⚠️ 注意事项:
allowed-origins*不可使用通配符 `**(除非allow-credentials: false`,但 WebSocket 通常需凭证支持);- 若前端为
https://app.example.com,此处必须写https://app.example.com,协议、域名、端口均需严格一致;allowed-methods必须包含GET(WebSocket 握手本质是 GET);allowed-headers应显式列出 WebSocket 升级必需头(尤其Sec-WebSocket-Key和Upgrade),避免因预检失败被拦截;- 生产环境建议按环境区分配置(如
dev,prod),避免硬编码。
验证是否生效:启动服务后,用 curl 模拟带 Origin 的升级请求:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
curl -i \ -H "Origin: http://dev.domain.com:8080" \ -H "Connection: Upgrade" \ -H "Upgrade: websocket" \ -H "Sec-WebSocket-Version: 13" \ -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \ http://localhost:8081/ws
若返回 HTTP/1.1 101 Switching Protocols 及 Access-Control-Allow-Origin: http://dev.domain.com:8080,则配置成功。
最后,在 Vue.js 客户端(如 vue-native-websocket-vue3)中确保连接 URL 使用 ws:// 或 wss:// 协议,并与后端端口、路径一致:
// Vue 3 setup script
import { createApp } from 'vue';
import { createStore } from 'vuex';
import VueNativeSock from 'vue-native-websocket-vue3';
const app = createApp(App);
app.use(VueNativeSock, 'ws://localhost:8081/ws', {
format: 'json',
reconnection: true,
reconnectionDelay: 1000,
store: createStore({ /* ... */ })
});总结:Micronaut 的 WebSocket 跨域不是“开启 CORS 即可”,而是通过具名 CORS 配置精准授权 Origin + 显式声明升级所需 Header。忽略此细节将导致静默 403,且服务层完全无日志——这是与普通 REST API 最易混淆的关键点。

















