Skip to main content
Version: 4.x

处理 CORS

配置

¥Configuration

从 Socket.IO v3 开始,你需要显式启用 跨域资源共享 (CORS)。

¥Since Socket.IO v3, you need to explicitly enable Cross-Origin Resource Sharing (CORS).

import { createServer } from "http";
import { Server } from "socket.io";

const httpServer = createServer();
const io = new Server(httpServer, {
cors: {
origin: "https://example.com"
}
});

所有选项都将转发到 cors 包。完整的选项列表可以在 此处 中找到。

¥All options will be forwarded to the cors package. The complete list of options can be found here.

带有 cookie (withCredentials) 和附加标头的示例:

¥Example with cookies (withCredentials) and additional headers:

// server-side
const io = new Server(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

¥Note: this also applies to localhost if your web application and your server are not served from the same port

const io = new Server(httpServer, {
cors: {
origin: "http://localhost:8080"
}
});

httpServer.listen(3000);

你可以使用 allowRequest 选项禁止所有跨域请求:

¥You can disallow all cross-origin requests with the allowRequest option:

const io = new Server(httpServer, {
allowRequest: (req, callback) => {
const noOriginHeader = req.headers.origin === undefined;
callback(null, noOriginHeader); // only allow requests without 'origin' header
}
});

故障排除

¥Troubleshooting

CORS 标头“Access-Control-Allow-Origin”缺失

¥CORS header ‘Access-Control-Allow-Origin’ missing

完整错误消息:

¥Full error message:

跨源请求被阻止:同源策略不允许读取 .../socket.io/?EIO=4&transport=polling&t=NMnp2WI 处的远程资源。(原因:CORS 标头“Access-Control-Allow-Origin”丢失)。

¥Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at .../socket.io/?EIO=4&transport=polling&t=NMnp2WI. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

如果你已正确配置服务器(请参阅 above),这可能意味着你的浏览器无法访问 Socket.IO 服务器。

¥If you have properly configured your server (see above), this could mean that your browser wasn't able to reach the Socket.IO server.

以下命令:

¥The following command:

curl "https://api.example.com/socket.io/?EIO=4&transport=polling"

应该返回类似:

¥should return something like:

0{"sid":"Lbo5JLzTotvW3g2LAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000}

如果情况并非如此,请检查你的服务器是否正在监听并且实际上可以在给定端口上访问。

¥If that's not the case, please check that your server is listening and is actually reachable on the given port.

如果 CORS 标头“Access-Control-Allow-Origin”为“*”,则不支持凭据

¥Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*

完整错误消息:

¥Full error message:

跨源请求被阻止:同源策略不允许读取“.../socket.io/?EIO=4&transport=polling&t=NvQfU77”处的远程资源。(原因:如果 CORS 标头“Access-Control-Allow-Origin”为“*”,则不支持凭据)

¥Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ‘.../socket.io/?EIO=4&transport=polling&t=NvQfU77’. (Reason: Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’)

你不能使用 origin: *withCredentials 设置为 true,你需要使用特定的原点:

¥You can't set withCredentials to true with origin: *, you need to use a specific origin:

import { createServer } from "http";
import { Server } from "socket.io";

const httpServer = createServer();
const io = new Server(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”

¥Expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’

完整错误消息:

¥Full error message:

跨源请求被阻止:同源策略不允许读取 .../socket.io/?EIO=4&transport=polling&t=NvQny19 处的远程资源。(原因:CORS 标头“Access-Control-Allow-Credentials”中预期为“true”)

¥Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at .../socket.io/?EIO=4&transport=polling&t=NvQny19. (Reason: expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’)

在这种情况下,withCredentials 在客户端上设置为 true,但服务器缺少 cors 选项中的 credentials 属性。请参阅上面的示例。

¥In that case, withCredentials is set to true on the client, but the server is missing the credentials attribute in the cors option. See the example above.