Решение проблемы CORS с запросом на localhost в Node.js
Быстрый ответ
Чтобы разрешить проблемы с CORS на localhost
, укажите в ответе сервера заголовок Access-Control-Allow-Origin: *
для снятия ограничений с любого источника, или "http://localhost:PORT"
, чтобы ограничить доступ определённого источника. Вот пример реализации на Node.js с помощью Express.js:
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:PORT');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
// Помните, использование звёздочек в качестве маски может быть рискованным.
next();
});
Не забудьте подставить вместо PORT
номер порта вашего веб-приложения. В продакшен-среде рекомендуется ограничить список разрешённых источников для улучшения безопасности.
Устранение проблем в Chrome и его ограничениях
Chrome может создавать трудности при работе с CORS на localhost
. Одно из решений — использование домена localho.st
, который также соответствует IP-адресу 127.0.0.1
.
http://localho.st:PORT
Если вы тестируете в Chrome, можно временно отключить безопасность:
chrome.exe --disable-web-security --user-data-dir="[путь к вашей директории]"
Однако учтите, что такое действие несёт в себе определённый риск.
Разработчикам на заметку: расширение для Chrome
Для тестирования вы можете использовать такие расширения Chrome, как "Allow-Control-Allow-Origin: *", которые автоматически добавляют заголовки CORS. Однако применение подобного в рабочей среде не рекомендуется.
Настройка сервера: делаем всё правильно
В случае отсутствия заголовка Access-Control-Allow-Origin
в ответе сервера, http://localhost
не будет разрешён:
Access-Control-Allow-Origin: http://localhost:PORT
Для более гибкой настройки CORS вы можете дополнить функционал, изучив исходный код указанного выше расширения для Chrome на GitHub.
Особенности клиентского кода
Ошибки CORS могут вызываться и клиентским кодом, например, при использовании объекта XMLHttpRequest
:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:PORT/data', true);
// Убедитесь, что протокол и порт установлены правильно, а настройки сервера корректны.
Преимущества использования прокси
Local-cors-proxy
может помочь обойти ограничения CORS. Установите его через npm и запустите прокси-сервер:
npm install -g local-cors-proxy
После этого обновите клиентский код таким образом, чтобы он обращался к прокси:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localho.st:PORT/proxy', true);
// Теперь CORS не мешает.
Визуализация
Представим политику CORS в виде правил входа в ночной клуб:
Ночной клуб "Localhost"
+-----------------------------------------------+
| Политика допуска на вход |
| +-------------------------------------------+ |
| | Список источников: только VIP-гости | |
| | 😃 vip.com | |
| | 😃 specialguest.com | |
| | 😐 localhost (Должен быть в списке!) | |
| | 😡 evil.com (Вход запрещён!) | |
| +-------------------------------------------+ |
| Если вашего имени нет в списке, вы не попадёте|
+-----------------------------------------------+
Попытка входа в Ночной клуб "Localhost":
- Гость с vip.com: [😃✅]
- Гость с specialguest.com:[😃✅]
- Гость с localhost: [😐❓] (Вход зависит от списка)
- Гость с evil.com: [😡🚫]
Так что знакомство с localhost
ещё не гарантирует доступ.
Управление предвзлётной проверкой
Для выполнения предвзлётной проверки браузеры могут воспользоваться методом OPTIONS
. Включение обработки таких запросов выглядит следующим образом:
app.options('*', (req, res) => {
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS,PUT,PATCH,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');
res.send(200);
// Теперь вы готовы к новым высотам!
});
Динамические источники и их проверка
В ситуациях, когда необходимо учесть изменчивость источников CORS, проверьте вхождение HTTP_ORIGIN
в список разрешённых доменов:
const allowedOrigins = ['http://localhost:3000', 'https://yourapp.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
// Вы в списке гостей – добро пожаловать!
}
PHP: корректное управление предвзлётной проверкой
header('Access-Control-Allow-Origin: *');
// Устанавливаем другие заголовки...
http_response_code(204); // Нет содержимого
exit(0);
// Задача выполнена спокойно и без лишних затруднений.
Важно завершать PHP-скрипты, которые обрабатывают предвзлётную проверку, командой exit(0)
.
Полезные материалы
- Cross-Origin Resource Sharing (CORS) — HTTP | MDN — полное руководство от MDN.
- web.dev — современные подходы к веб-разработке от Google.
- enable cross-origin resource sharing — инструкции по включению CORS на различных серверах.
- Express cors middleware — официальная документация по использованию CORS в Express.js.
- CORS Module Configuration Reference | Microsoft Learn — настройка CORS на IIS.
- Handling CORS with Node.js — управление CORS в Node.js.