处理 CORS
配置
从 Socket.IO v3 开始,您需要显式启用跨域资源共享(CORS)。
import{ createServer }from"http";
import{Server}from"socket.io";
const httpServer =createServer();
const io =newServer(httpServer,{
cors:{
origin:"https://example.com"
}
});
所有选项都将转发到cors包。可以在此处找到完整的选项列表。
带有 cookie ( withCredentials) 和附加标头的示例:
// server-side
const io =newServer(httpServer,{
cors:{
origin:"https://example.com",
allowedHeaders:["my-custom-header"],
credentials:true
}
});
// client-side
import{ io }from"socket.io-client";
const socket =io("https://api.example.com",{
withCredentials:true,
extraHeaders:{
"my-custom-header":"abcd"
}
});
注意:如果您的 Web 应用程序和服务器不是从同一个端口提供服务,这也适用于 localhost
const io =newServer(httpServer,{
cors:{
origin:"http://localhost:8080"
}
});
httpServer.listen(3000);
您可以使用以下选项禁止所有跨域请求allowRequest option:
const io =newServer(httpServer,{
allowRequest:(req, callback)=>{
const noOriginHeader = req.headers.origin===undefined;
callback(null, noOriginHeader);
}
});
故障排除
缺少 CORS 标头"Access-Control-Allow-Origin"
完整的错误信息:
跨域请求被阻止:同源策略不允许读取位于 .../socket.io/?EIO=4&transport=polling&t=NMnp2WI 的远程资源。(原因:缺少 CORS 标头"Access-Control-Allow-Origin")。
如果您已正确配置您的服务器(见上文),这可能意味着您的浏览器无法访问 Socket.IO 服务器。
以下命令:
curl "https://api.example.com/socket.io/?EIO=4&transport=polling"
应该返回类似:
0{"sid":"Lbo5JLzTotvW3g2LAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000}
如果不是这种情况,请检查您的服务器是否正在侦听并且实际上可以在给定端口上访问。
如果 CORS 标头"Access-Control-Allow-Origin"为"*",则不支持凭据
完整的错误信息:
跨域请求被阻止:同源策略不允许读取位于".../socket.io/?EIO=4&transport=polling&t=NvQfU77"的远程资源。(原因:如果 CORS 标头"Access-Control-Allow-Origin"为"*",则不支持凭证)
您不能同时设置withCredentials 为 true 和 origin: *,您需要使用特定的来源:
import{ createServer }from"http";
import{Server}from"socket.io";
const httpServer =createServer();
const io =newServer(httpServer,{
cors:{
origin:"https://my-frontend.com",
// or with an array of origins
// origin: ["https://my-frontend.com", "https://my-other-frontend.com", "http://localhost:3000"],
credentials:true
}
});
CORS 标头"Access-Control-Allow-Credentials"中预期为"true"
完整的错误信息:
跨域请求被阻止:同源策略不允许读取位于 .../socket.io/?EIO=4&transport=polling&t=NvQny19 的远程资源。(原因:CORS 标头"Access-Control-Allow-Credentials"中预期为"true")
在这种情况下,在客户端上withCredentials设置为true,但服务器缺少选项credentials中的属性cors 。请参见上面的示例。