Обработка CORS
Настройка
С версии Socket.IO v3 необходимо явно включить 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. Полный список параметров можно найти здесь.
Пример с куками (withCredentials) и дополнительными заголовками:
// 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"
}
});
Примечание: это также относится к localhost, если ваше веб-приложение и сервер не обслуживаются с одного порта.
const io = new Server(httpServer, {
cors: {
origin: "http://localhost:8080"
}
});
httpServer.listen(3000);
Вы можете запретить все запросы с других доменов с помощью параметра allowRequest:
const io = new Server(httpServer, {
allowRequest: (req, callback) => {
const noOriginHeader = req.headers.origin === undefined;
callback(null, noOriginHeader); // only allow requests without 'origin' header
}
});
Поиск ошибок
Отсутствует заголовок 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 = 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
}
});
Ожидается ‘true’ в заголовке CORS ‘Access-Control-Allow-Credentials’
Полное сообщение об ошибке:
Запрос с другого домена заблокирован: политика одного домена запрещает чтение удаленного ресурса по адресу .../socket.io/?EIO=4&transport=polling&t=NvQny19. (Причина: ожидается ‘true’ в заголовке CORS ‘Access-Control-Allow-Credentials’)
В этом случае, withCredentials установлено на true на клиенте, но на сервере отсутствует атрибут credentials в параметре cors. См. пример выше.
© 2014–2021 Automattic
Licensed under the MIT License.
https://socket.io/docs/v4/handling-cors