Як виправити відсутність заголовка CORS Access-Control-Allow-Origin в Express.js

Якщо браузер повідомляє про помилку CORS header 'Access-Control-Allow-Origin' missing, важливою підказкою є не те, що Express.js не отримав запит. Браузер вказує на те, що відповідь не містила заголовка CORS, який дозволяє сторінці читати цю відповідь. Тому виправлення має бути виконано на сервері або проксі-сервері, яким ви керуєте, а не через випадкові налаштування на стороні клієнта.

Ілюстративний приклад, що використовується в цьому посібнику: уявіть панель завдань, що працює за адресою http://localhost:5173 і викликає API Express за адресою http://localhost:3000/api/tasks. Браузер блокує JavaScript від читання відповіді API, оскільки API не повертає заголовок Access-Control-Allow-Origin. Це гіпотетичний навчальний приклад, а не твердження про реальний тест, продукт або розгортання.

Станом на 11 вересня 2026 року офіційна документація проміжного ПЗ CORS для Express вказує версію cors 2.8.6 і описує її як проміжне ПЗ, що встановлює заголовки відповіді CORS. Поточний список пакетів Express належить до покоління 5.x, тому цей посібник віддає перевагу проміжному ПЗ рівня додатка замість опори на старіші шаблони маршрутів із підстановочними символами.

Що насправді означає ця помилка

Веб-сторінка має походження (origin), що складається зі схеми, хоста та порту. У прикладі http://localhost:5173 та http://localhost:3000 є різними походженнями, оскільки їхні порти відрізняються. Політика одного походження браузера зазвичай забороняє JavaScript з одного походження читати ресурси з іншого, якщо цільовий сервер не повертає відповідні заголовки спільного використання ресурсів між джерелами (CORS).

Документація MDN для цієї конкретної помилки пояснює, що у відповіді відсутній необхідний заголовок Access-Control-Allow-Origin. Якщо ви керуєте сервером, вам слід налаштувати походження запитуваного сайту як дозволене. Для публічних API без облікових даних може бути доречним *; для приватних API або API з обліковими даними використовуйте конкретні довірені походження. Див. пояснення MDN щодо помилки відсутності Access-Control-Allow-Origin.

Крок 1: Підтвердіть, що проблема в CORS, і визначте точне походження

Ілюстрація інструментів розробника браузера, згенерована ШІ, що показує помилку CORS через відсутність Access-Control-Allow-Origin для запиту з localhost порту 5173 до API Express на порту 3000
Ілюстрація, згенерована ШІ, а не реальний скріншот: браузер повідомляє, що у відповіді Express відсутній заголовок Access-Control-Allow-Origin.

Відкрийте інструменти розробника браузера та перевірте панелі Console та Network. Запишіть походження фронтенду точно так, як його надсилає браузер. У нашому ілюстративному випадку це http://localhost:5173.

Не зводьте походження лише до імені хоста. Це різні походження: http://localhost:5173, http://localhost:3000, http://127.0.0.1:5173 та https://localhost:5173. Список дозволів у продакшн-середовищі також має розрізняти https://app.example.com та інші схеми, хости, порти або піддомени, якщо ви навмисно не дозволяєте їх.

Якщо відповідь API є помилкою 404, 500, перенаправленням, помилкою автентифікації або сторінкою помилки, згенерованою проксі, перевірте також цю відповідь. Заголовки CORS мають бути присутніми у відповіді, яку фактично отримує браузер. Виправлення маршруту додатка не допоможе, якщо зворотний проксі, CDN, балансир навантаження або обробник помилок повертають іншу відповідь без цього заголовка.

Крок 2: Встановіть і завантажте офіційне проміжне ПЗ CORS для Express

Ілюстрація редактора коду, згенерована ШІ, що показує команду npm install cors та імпортування express і cors у server.js
Ілюстрація, згенерована ШІ, а не реальний скріншот: встановіть проміжне ПЗ cors, яке підтримується Express, і завантажте його на сервері.

Для більшості додатків Express найменш схильним до помилок рішенням є проміжне ПЗ cors, яке підтримується проєктом Express. Офіційна сторінка проміжного ПЗ Express перелічує його серед інструментів, що підтримуються командою Express.js. Встановіть його у вашому проєкті API:

npm install cors

Потім завантажте його поруч із Express:

const express = require('express');
const cors = require('cors');

const app = express();

Офіційна документація доступна за адресою документація проміжного ПЗ cors для Express.js. Express також документує, як проміжне ПЗ рівня додатка виконується в порядку запитів, у розділі Express.js: Використання проміжного ПЗ.

Крок 3: Свідомо дозвольте походження фронтенду

Ілюстрація редактора коду, згенерована ШІ, що показує app.use з cors origin, встановленим на http localhost порт 5173, перед маршрутом API Express
Ілюстрація, згенерована ШІ, а не реальний скріншот: налаштуйте CORS перед маршрутами API, щоб дозволене походження отримувало заголовок відповіді.

Для гіпотетичної панелі керування налаштуйте точне походження середовища розробки перед маршрутами, яким потрібен CORS:

const express = require('express');
const cors = require('cors');

const app = express();

const corsOptions = {
  origin: 'http://localhost:5173'
};

app.use(cors(corsOptions));
app.use(express.json());

app.get('/api/tasks', (req, res) => {
  res.json({ tasks: ['Learn Express', 'Build API'] });
});

app.listen(3000);

Розміщення app.use(cors(corsOptions)) перед маршрутами API важливе, оскільки Express обробляє проміжне ПЗ послідовно. Проміжному ПЗ потрібна можливість додати заголовки відповіді до того, як маршрут або раніше визначене проміжне ПЗ завершить запит.

Для справді публічного API, який не використовує облікові дані, app.use(cors()) використовує дозвільну поведінку походження за замовчуванням. Це зручно, але не має бути вашим автоматичним вибором для продакшн-середовища. MDN рекомендує обмежувати Access-Control-Allow-Origin мінімально необхідними походженнями та ресурсами. Див. рекомендації MDN щодо безпеки CORS.

Дозвольте кілька відомих походжень, не дозволяючи всім

Типова конфігурація продакшн-середовища включає локальний фронтенд, фронтенд для тестування (staging) та продакшн-фронтенд. Використовуйте список дозволів і перевіряйте вхідне походження:

const allowedOrigins = new Set([
  'http://localhost:5173',
  'https://staging.example.com',
  'https://app.example.com'
]);

const corsOptions = {
  origin(origin, callback) {
    if (!origin || allowedOrigins.has(origin)) {
      callback(null, true);
      return;
    }
    callback(new Error('Origin not allowed by CORS'));
  }
};

app.use(cors(corsOptions));

Гілка !origin дозволяє клієнтам, які не надсилають заголовок Origin, таким як багато запитів «сервер-сервер» та інструменти командного рядка. Чи хочете ви такої поведінки, є рішенням політики додатка; сам по собі CORS не є автентифікацією.

Крок 4: Перевірте простий запит і будь-який попередній запит (preflight)

Ілюстрація панелі Network браузера, згенерована ШІ, що показує відповіді OPTIONS 204 та GET 200, а також Access-Control-Allow-Origin, встановлений на localhost порт 5173
Ілюстрація, згенерована ШІ, а не реальний скріншот: переконайтеся, що браузер отримує очікуваний заголовок CORS і що будь-який попередній запит OPTIONS завершується успішно.

Перезавантажте фронтенд і перевірте панель Network. Умовою успіху є не просто статус 200. Перевірте заголовки відповіді. У нашому ілюстративному випадку відповідь API повинна містити значення походження, еквівалентне:

Access-Control-Allow-Origin: http://localhost:5173

Деякі міжпоходження запити запускають попередній запит (preflight): браузер надсилає запит OPTIONS перед реальним запитом, щоб перевірити, чи дозволені метод і заголовки. Запити з використанням методів, таких як PUT або DELETE, або певних користувацьких/запитових заголовків, зазвичай потребують попереднього запиту. Коли cors встановлено як проміжне ПЗ рівня додатка за допомогою app.use(cors(...)), офіційна документація Express стверджує, що попередні запити обробляються для всіх маршрутів.

Ви також можете перевірити заголовки поза браузером, не стверджуючи, що клієнт командного рядка застосовує CORS:

curl -i   -H "Origin: http://localhost:5173"   http://localhost:3000/api/tasks

Це корисно для того, щоб побачити, що повертає сервер, але успішний запит через curl або API-клієнт не доводить, що браузерний CORS налаштовано правильно. Документація CORS для Express явно зазначає, що CORS застосовується браузерами; небраузерні клієнти не застосовують таких самих обмежень на читання.

Запити з обліковими даними: не поєднуйте облікові дані з підстановочним знаком у походженні

Якщо фронтенд повинен надсилати файли cookie або HTTP-автентифікацію між походженнями, обидві сторони потребують сумісних налаштувань. На стороні Express налаштуйте конкретне довірене походження та увімкніть облікові дані:

app.use(cors({
  origin: 'https://app.example.com',
  credentials: true
}));

На стороні браузера запит fetch, якому потрібні файли cookie, зазвичай використовує credentials: 'include'. Не змінюйте походження сервера на * для запиту з обліковими даними. Браузери не приймають підстановочний знак Access-Control-Allow-Origin разом із CORS з обліковими даними так, як часто очікують розробники, а необмежене походження також буде поганим кордоном безпеки.

Чому типові «виправлення» не працюють

СпробаЧому це не вирішує справжню проблемуКращий підхід
Встановіть mode: 'no-cors' у fetchВідповідь стає непрозорою, тому JavaScript не може прочитати тіло відповіді або більшість заголовків.Налаштуйте CORS на сервері, яким ви керуєте.
Тестуйте лише в Postman або curlЦі клієнти не застосовують політику браузерного CORS.Перевіряйте фактичні заголовки запиту та відповіді браузера.
Використовуйте Access-Control-Allow-Origin: * всюдиЦе надмірно широко для приватних API і несумісно з типовими налаштуваннями з обліковими даними.Дозволяйте лише довірені походження, якщо API не є повністю публічним.
Додайте кілька заголовків Access-Control-Allow-OriginБраузери очікують єдине значення дозволеного походження, а не кілька копій або список походжень, розділених комами.Перевіряйте походження запиту та повертайте одне відповідне значення.
Змінюйте код фронтенду повторноВідсутній заголовок знаходиться у відповіді сервера.Виправте Express або проксі, який генерує остаточну відповідь.

Коли код Express виглядає правильно, але помилка залишається

Якщо чотири кроки вище не вирішили помилку, відстежуйте весь шлях запиту, замість того щоб сліпо додавати більше заголовків.

  • Перевірте порядок проміжного ПЗ. Проміжне ПЗ CORS має виконуватися до маршрутів або обробників, які завершують відповідь.
  • Перевірте перенаправлення. Браузер може отримувати відповідь з іншої URL-адреси або походження після перенаправлення.
  • Перевірте поведінку проксі/CDN. Nginx, шлюз, безсерверна платформа або CDN можуть додавати, видаляти, дублювати або замінювати заголовки.
  • Перевірте відповіді з помилками. Звичайна відповідь 200 може містити заголовки CORS, тоді як відповідь 401, 404 або 500 — ні.
  • Перевірте літеральне походження. Схема, ім'я хоста та порт мають значення; localhost та 127.0.0.1 не є взаємозамінними для зіставлення CORS.
  • Перевірте наявність дубльованих заголовків. MDN документує, що кілька заголовків Access-Control-Allow-Origin не дозволені. Див. MDN щодо кількох заголовків Access-Control-Allow-Origin.

Ручні заголовки проти проміжного ПЗ cors

Ви можете встановлювати заголовки CORS вручну за допомогою API відповідей Express, але легко пропустити поведінку попередніх запитів, правила щодо облікових даних, динамічне зіставлення походження, Vary: Origin або шляхи помилок. Офіційне проміжне ПЗ cors вже надає опції для origin, методів, дозволених заголовків, відкритих заголовків, облікових даних, поведінки попередніх запитів та максимального віку кешування. Для більшості проєктів Express використання цього проміжного ПЗ робить політику явною та простішою для перевірки.

Якщо ви реалізуєте динамічну логіку походження самостійно, ніколи не відображайте автоматично кожне вхідне значення Origin лише тому, що воно присутнє. Перевіряйте його щодо довіреного набору. MDN попереджає, що необмежене читання між походженнями може експонувати дані, особливо коли задіяні облікові дані.

Практичний чек-лист для продакшн-середовища

  • Перелічіть точні походження фронтенду, які повинні мати можливість читати API.
  • Використовуйте HTTPS-походження у продакшн-середовищі та тримайте походження середовища розробки окремо.
  • Встановіть проміжне ПЗ CORS перед захищеними маршрутами API, яким воно потрібне.
  • Використовуйте конкретні походження для приватних або захищених обліковими даними кінцевих точок.
  • Перевіряйте як звичайні відповіді, так і відповіді попередніх запитів OPTIONS у браузері.
  • Перевіряйте шляхи помилок, такі як відповіді 401, 404 та 500, якщо вони можуть повертатися між походженнями.
  • Розглядайте CORS як політику читання браузера, а не як автентифікацію або авторизацію.

В ілюстративному сценарії панелі завдань стійке виправлення є прямим: визначте точне походження фронтенду, налаштуйте Express на повернення відповідного заголовка CORS, дозвольте проміжному ПЗ рівня додатка обробляти попередні запити та перевірте заголовки у відповіді, яку фактично отримує браузер. Якщо заголовок все ще відсутній після цього, наступним підозрюваним зазвичай є порядок проміжного ПЗ або інфраструктура між браузером і Express, а не сам виклик fetch на фронтенді.

Офіційні посилання

Залишити коментар

Як виправити помилку “Prisma Client Has Not Been Generated Yet”

Як виправити помилку “Prisma Client Has Not Been Generated Yet”

Виправте помилку незгенерованого Prisma Client, перевіривши генератор, схему, шлях виводу, імпорти, версії, налаштування монорепозиторію та кроки збірки під час розгортання.

Як виправити помилку SSL-сертифіката: не вдалося отримати локальний сертифікат емітента в Git

Як виправити помилку SSL-сертифіката: не вдалося отримати локальний сертифікат емітента в Git

Виправте помилку Git «не вдалося отримати локальний сертифікат емітента», визначивши механізм довіри, встановивши правильний ланцюжок ЦС та зберігаючи перевірку SSL увімкненою.

Як виправити помилку таймауту мережі MongoDB у з'єднанні Mongoose

Як виправити помилку таймауту мережі MongoDB у з'єднанні Mongoose

Виправте помилки таймауту мережі MongoDB у Mongoose, визначивши тип таймауту, перевіривши доступність Atlas або TCP, виправивши URI та налаштувавши таймаути лише за необхідності.

Як виправити помилку «Execution Policy Restricted» у Windows PowerShell

Як виправити помилку «Execution Policy Restricted» у Windows PowerShell

Виправте помилку обмеженої політики виконання PowerShell, перевіривши область дії та групову політику, а потім обравши RemoteSigned, Unblock-File або тимчасовий параметр сесії.

Як виправити помилку npm ERR! code ERESOLVE: конфлікт залежностей-партнерів

Як виправити помилку npm ERR! code ERESOLVE: конфлікт залежностей-партнерів

Виправте конфлікти залежностей-партнерів npm ERESOLVE, визначивши несумісний діапазон пакетів, узгодивши версії, використовуючи npm explain та npm ls, а також розглядаючи legacy-peer-deps або force лише як контрольовані резервні варіанти.

Як виправити помилку підключення Redis до 127.0.0.1:6379

Як виправити помилку підключення Redis до 127.0.0.1:6379

Виправте помилки відмови у підключенні Redis на 127.0.0.1:6379, перевіривши сервер, порт, мережу Docker, redis.conf, автентифікацію та TLS.

Як виправити внутрішню помилку 500 у серверних компонентах Next.js

Як виправити внутрішню помилку 500 у серверних компонентах Next.js

Виправте помилки 500 у серверних компонентах Next.js, аналізуючи логи сервера, перевіряючи запити даних та змінні середовища, обробляючи помилки та перевіряючи збірку для продакшену.

Як виправити помилку CrashLoopBackOff у Kubernetes у локальному Minikube

Як виправити помилку CrashLoopBackOff у Kubernetes у локальному Minikube

Діагностуйте та виправляйте помилку CrashLoopBackOff у Kubernetes у локальному Minikube, перевіряючи стан пода, попередні логи, причини завершення роботи, проби, конфігурацію, ліміти пам’яті та стан кластера.

Як виправити помилку «Docker Desktop Engine Stopped» у Windows 11

Як виправити помилку «Docker Desktop Engine Stopped» у Windows 11

Виправте помилку «Docker Desktop Engine Stopped» у Windows 11, перевіривши статус Docker, оновивши та перезавантаживши WSL 2, підтвердивши віртуалізацію та використавши діагностику перед скиданням налаштувань.

Як виправити помилку Uncaught ReferenceError: process is not defined у Vite

Як виправити помилку Uncaught ReferenceError: process is not defined у Vite

Виправте помилку 'process is not defined' у Vite, замінивши використання process.env у стилі Node.js, правильно налаштувавши змінні VITE_ та перевіривши залежності.