laravel 10 本身不提供 websocket 服务,需依赖 pusher、redis+soketi 或 beyondcode/laravel-websockets 等广播驱动;cors 问题实际源于 websocket 服务器(非 laravel 应用层),其 allowed_origins 需显式配置前端地址,且生产环境禁用 ['*'];私有频道认证接口 /api/broadcasting/auth 才受 laravel cors 控制,需在 config/cors.php 中正确设置允许来源、凭证支持等。

Laravel 10 本身不直接提供 WebSocket 服务,它依赖广播驱动(如 Pusher、Redis + Soketi、beyondcode/laravel-websockets)来实现 WebSocket 通信。而 CORS(跨域资源共享)问题通常不出现在 Laravel 应用层,而是出在 WebSocket 服务器本身——比如你用 beyondcode/laravel-websockets 或 Soketi 自建服务时,前端访问 ws://localhost:6001 才会触发浏览器的跨域检查(注意:WebSocket 协议本身不遵循 HTTP CORS 机制,但浏览器在建立连接前会发送一个 HTTP Upgrade 请求,该请求受同源策略影响,实际表现为“连接被拒绝”或“400/403 错误”,常被误认为是 CORS)。
所以准确说:不是 Laravel 配置 WebSocket 的 CORS,而是 WebSocket 服务器要允许指定来源的连接请求。
以下是常见场景下的配置要点:
WebSocket 服务器需配置允许的来源(Origin)
以 beyondcode/laravel-websockets 为例(Laravel 官方推荐的自托管方案):
在 config/websockets.php 中设置:
'allowed_origins' => [
'http://localhost:3000',
'https://your-frontend.com',
'http://127.0.0.1:8000', // 如果前端和 Laravel 同域开发
],
⚠️ 注意:
-
allowed_origins是严格匹配的,不支持通配符*(除非设为['*'],但仅限开发环境,生产环境禁止); - 若前端运行在
http://localhost:5173(Vite),这里必须显式加上; - 空数组
[]或未配置 → 默认拒绝所有跨域连接,导致WebSocket connection to 'ws://...' failed: Error during WebSocket handshake。
Laravel 后端 API 的 CORS 配置(辅助作用)
虽然 WebSocket 连接不走 Laravel 路由,但前端首次认证私有频道时,会向 Laravel 发起一个 HTTP POST 请求(默认路径 /api/broadcasting/auth),这个请求确实受 Laravel 的 CORS 控制。
你需要确保该接口允许前端域名访问:
使用 fruitcake/laravel-cors(Laravel 10 默认已集成 laravel/sanctum,但 CORS 仍需单独配):
在 config/cors.php 中:
'supports_credentials' => true, 'allowed_origins' => ['http://localhost:3000', 'https://your-frontend.com'], 'allowed_methods' => ['*'], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 3600,
并在 app/Http/Kernel.php 的 $middlewareGroups['api'] 中确认已启用:
\Fruitcake\Cors\HandleCors::class,
Laravel Echo 前端配置要与后端对齐
前端用 Laravel Echo 连接时,authEndpoint 必须指向 Laravel API 的认证地址,且协议、域名、端口需匹配 CORS 白名单:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
const echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
wsHost: import.meta.env.VITE_WS_HOST || window.location.hostname,
wsPort: import.meta.env.VITE_WS_PORT || 6001,
wssPort: import.meta.env.VITE_WSS_PORT || 6001,
forceTLS: false, // 开发环境用 ws,生产建议 wss
disableStats: true,
enabledTransports: ['ws', 'wss'],
authEndpoint: 'http://localhost:8000/api/broadcasting/auth', // ← 这个 URL 必须在 CORS 允许列表中
});
小结关键点
- WebSocket 连接失败报 400/403/Network Error?先查
allowed_origins是否包含前端地址; - 私有频道认证失败(401/419)?检查
/api/broadcasting/auth是否通过 CORS; - 不要用
*在生产环境开放allowed_origins或Access-Control-Allow-Origin: *配合credentials: true(会直接被浏览器拦截); -
forceTLS: true时,wsHost必须是 HTTPS 域名,且wssPort对应 TLS 端口(如 443 或反代后的 6001); - 使用 Nginx 反代 WebSocket 时,还需额外配置
Upgrade和Connection头(这不是 Laravel 配置范畴,但常是线上部署卡点)。
不复杂但容易忽略。











