Головна
» Базові знання
»
Як виправити відсутність заголовка CORS Access-Control-Allow-Origin в Express.js
Як виправити відсутність заголовка 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, і визначте точне походження
Ілюстрація, згенерована ШІ, а не реальний скріншот: браузер повідомляє, що у відповіді 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
Ілюстрація, згенерована ШІ, а не реальний скріншот: встановіть проміжне ПЗ cors, яке підтримується Express, і завантажте його на сервері.
Для більшості додатків Express найменш схильним до помилок рішенням є проміжне ПЗ cors, яке підтримується проєктом Express. Офіційна сторінка проміжного ПЗ Express перелічує його серед інструментів, що підтримуються командою Express.js. Встановіть його у вашому проєкті API:
Розміщення 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)
Ілюстрація, згенерована ШІ, а не реальний скріншот: переконайтеся, що браузер отримує очікуваний заголовок CORS і що будь-який попередній запит OPTIONS завершується успішно.
Перезавантажте фронтенд і перевірте панель Network. Умовою успіху є не просто статус 200. Перевірте заголовки відповіді. У нашому ілюстративному випадку відповідь API повинна містити значення походження, еквівалентне:
Деякі міжпоходження запити запускають попередній запит (preflight): браузер надсилає запит OPTIONS перед реальним запитом, щоб перевірити, чи дозволені метод і заголовки. Запити з використанням методів, таких як PUT або DELETE, або певних користувацьких/запитових заголовків, зазвичай потребують попереднього запиту. Коли cors встановлено як проміжне ПЗ рівня додатка за допомогою app.use(cors(...)), офіційна документація Express стверджує, що попередні запити обробляються для всіх маршрутів.
Ви також можете перевірити заголовки поза браузером, не стверджуючи, що клієнт командного рядка застосовує CORS:
Це корисно для того, щоб побачити, що повертає сервер, але успішний запит через curl або API-клієнт не доводить, що браузерний CORS налаштовано правильно. Документація CORS для Express явно зазначає, що CORS застосовується браузерами; небраузерні клієнти не застосовують таких самих обмежень на читання.
Запити з обліковими даними: не поєднуйте облікові дані з підстановочним знаком у походженні
Якщо фронтенд повинен надсилати файли cookie або HTTP-автентифікацію між походженнями, обидві сторони потребують сумісних налаштувань. На стороні Express налаштуйте конкретне довірене походження та увімкніть облікові дані:
На стороні браузера запит fetch, якому потрібні файли cookie, зазвичай використовує credentials: 'include'. Не змінюйте походження сервера на * для запиту з обліковими даними. Браузери не приймають підстановочний знак Access-Control-Allow-Origin разом із CORS з обліковими даними так, як часто очікують розробники, а необмежене походження також буде поганим кордоном безпеки.
Чому типові «виправлення» не працюють
Спроба
Чому це не вирішує справжню проблему
Кращий підхід
Встановіть mode: 'no-cors' у fetch
Відповідь стає непрозорою, тому JavaScript не може прочитати тіло відповіді або більшість заголовків.
Налаштуйте CORS на сервері, яким ви керуєте.
Тестуйте лише в Postman або curl
Ці клієнти не застосовують політику браузерного CORS.
Перевіряйте фактичні заголовки запиту та відповіді браузера.
Ви можете встановлювати заголовки CORS вручну за допомогою API відповідей Express, але легко пропустити поведінку попередніх запитів, правила щодо облікових даних, динамічне зіставлення походження, Vary: Origin або шляхи помилок. Офіційне проміжне ПЗ cors вже надає опції для origin, методів, дозволених заголовків, відкритих заголовків, облікових даних, поведінки попередніх запитів та максимального віку кешування. Для більшості проєктів Express використання цього проміжного ПЗ робить політику явною та простішою для перевірки.
Якщо ви реалізуєте динамічну логіку походження самостійно, ніколи не відображайте автоматично кожне вхідне значення Origin лише тому, що воно присутнє. Перевіряйте його щодо довіреного набору. MDN попереджає, що необмежене читання між походженнями може експонувати дані, особливо коли задіяні облікові дані.
Практичний чек-лист для продакшн-середовища
Перелічіть точні походження фронтенду, які повинні мати можливість читати API.
Використовуйте HTTPS-походження у продакшн-середовищі та тримайте походження середовища розробки окремо.
Встановіть проміжне ПЗ CORS перед захищеними маршрутами API, яким воно потрібне.
Використовуйте конкретні походження для приватних або захищених обліковими даними кінцевих точок.
Перевіряйте як звичайні відповіді, так і відповіді попередніх запитів OPTIONS у браузері.
Перевіряйте шляхи помилок, такі як відповіді 401, 404 та 500, якщо вони можуть повертатися між походженнями.
Розглядайте CORS як політику читання браузера, а не як автентифікацію або авторизацію.
В ілюстративному сценарії панелі завдань стійке виправлення є прямим: визначте точне походження фронтенду, налаштуйте Express на повернення відповідного заголовка CORS, дозвольте проміжному ПЗ рівня додатка обробляти попередні запити та перевірте заголовки у відповіді, яку фактично отримує браузер. Якщо заголовок все ще відсутній після цього, наступним підозрюваним зазвичай є порядок проміжного ПЗ або інфраструктура між браузером і Express, а не сам виклик fetch на фронтенді.