Как да поправите липсващия CORS заглавен ред Access-Control-Allow-Origin в Express.js

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

Илюстративен пример, използван в това ръководство: представете си таблица с задачи, работеща на http://localhost:5173, която извиква Express API на http://localhost:3000/api/tasks. Браузърът блокира JavaScript да прочете отговора от API, защото API не връща Access-Control-Allow-Origin. Това е хипотетичен учебен пример, а не твърдение за реален тест, продукт или внедряване.

Както е проверено на 11 септември 2026 г., официалната документация за Express CORS middleware посочва версия 2.8.6 на cors и я описва като middleware, което задава CORS заглавни редове в отговора. Текущият списък с пакети на Express е от серията 5.x, затова това ръководство предпочита middleware на ниво приложение, вместо да разчита на по-стари шаблони за маршрути с wildcard.

Какво всъщност означава грешката

Уеб страницата има произход (origin), съставен от схемата, хоста и порта ѝ. В примера http://localhost:5173 и http://localhost:3000 са различни произходи, защото портовете им се различават. Политиката на браузъра за един и същи произход (same-origin policy) обикновено предотвратява JavaScript от един произход да чете ресурси от друг, освен ако целевият сървър не върне подходящи заглавни редове за Cross-Origin Resource Sharing (CORS).

Документацията на MDN за тази конкретна грешка обяснява, че в отговора липсва задължителният заглавен ред Access-Control-Allow-Origin. Ако контролирате сървъра, трябва да конфигурирате произхода на заявяващия сайт като разрешен произход. За публични API без удостоверяване (non-credentialed), * може да е подходящ; за частни или удостоверяващи API използвайте конкретни доверени произходи. Вижте обяснението на MDN за липсващата грешка Access-Control-Allow-Origin.

Стъпка 1: Потвърдете, че CORS е проблемът, и идентифицирайте точния произход

Илюстрация на DevTools на браузъра, генерирана от AI, показваща липсваща CORS грешка Access-Control-Allow-Origin за заявка от порт 5173 на localhost към Express API на порт 3000
Илюстрация, генерирана от AI, а не реален екранен снимка: браузърът докладва, че в отговора на 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: Инсталирайте и заредете официалния Express CORS middleware

Илюстрация на редактор за код, генерирана от AI, показваща командата npm install cors и импортирането на express и cors в server.js
Илюстрация, генерирана от AI, а не реален екранен снимка: инсталирайте cors middleware, поддържан от Express, и го заредете в сървъра.

За повечето Express приложения най-малко податливото на грешки решение е cors middleware, поддържано от проекта Express. Официалната страница с middleware на Express го изброява сред middleware, поддържани от екипа на Express.js. Инсталирайте го във вашия API проект:

npm install cors

След това го заредете до Express:

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

const app = express();

Официалната документация е налична на документацията за Express.js cors middleware. Express също така документира как middleware на ниво приложение се изпълнява в реда на заявките на Express.js: Използване на middleware.

Стъпка 3: Разрешете произхода на фронтенда умишлено

Илюстрация на редактор за код, генерирана от AI, показваща app.use с cors origin, зададен на http localhost порт 5173 преди маршрут на Express API
Илюстрация, генерирана от AI, а не реален екранен снимка: конфигурирайте 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 обработва middleware в ред. Middleware трябва да има възможност да добави заглавни редове на отговора, преди маршрут или по-ранен middleware да прекрати заявката.

За наистина публично API, което не използва удостоверяващи данни, app.use(cors()) използва поведението по подразбиране на middleware за разрешен произход. Това е удобно, но не трябва да е вашият автоматичен избор за производство. 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 на браузъра, генерирана от AI, показваща отговори OPTIONS 204 и GET 200, плюс Access-Control-Allow-Origin, зададен на localhost порт 5173
Илюстрация, генерирана от AI, а не реален екранен снимка: проверете дали браузърът получава очаквания CORS заглавен ред и дали всяка предварителна заявка OPTIONS успява.

Презаредете фронтенда и проверете панела Network. Условието за успех не е просто статус 200. Проверете заглавните редове на отговора. В нашия илюстративен случай отговорът на API трябва да включва стойност за произход, еквивалентна на:

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

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

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

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

Това е полезно, за да видите какво връща сървърът, но успешна заявка с curl или API клиент не доказва, че CORS в браузъра е конфигуриран правилно. Документацията на Express за CORS изрично отбелязва, че CORS се прилага от браузърите; небраузърни клиенти не прилагат същото ограничение за четене.

Заявки с удостоверяващи данни: не комбинирайте удостоверяващи данни с wildcard произход

Ако фронтендът трябва да изпраща бисквитки или HTTP удостоверяване между различни произходи, и двете страни се нуждаят от съвместими настройки. От страната на Express конфигурирайте конкретен доверен произход и активирайте удостоверяващите данни:

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

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

Защо честите „решения“ се провалят

ОпитЗащо не решава истинския проблемПо-добър подход
Задайте mode: 'no-cors' във fetchОтговорът става непрозрачен (opaque), така че JavaScript не може да прочете тялото на отговора или повечето заглавни редове.Конфигурирайте CORS на сървъра, който контролирате.
Тествайте само в Postman или curlТези клиенти не прилагат политиката на браузъра за CORS.Инспектирайте действителните заглавни редове на заявката и отговора в браузъра.
Използвайте Access-Control-Allow-Origin: * навсякъдеТова е ненужно широко за частни API и несъвместимо с често срещани конфигурации с удостоверяващи данни.Разрешавайте само доверени произходи, когато API не е напълно публично.
Добавете няколко Access-Control-Allow-Origin заглавни редаБраузърите очакват една стойност за разрешен произход, а не множество копия или списък с произходи, разделени със запетаи.Валидирайте произхода на заявката и върнете една съвпадаща стойност.
Променяйте кода на фронтенда многократноЛипсващият заглавен ред е в отговора на сървъра.Поправете Express или проксито, което генерира крайния отговор.

Когато кодът на Express изглежда правилен, но грешката остава

Ако четирите стъпки по-горе не отстранят грешката, проследете целия път на заявката, вместо да добавяте сляпо повече заглавни редове.

  • Проверете реда на middleware. CORS middleware трябва да се изпълнява преди маршрути или обработчици, които прекратяват отговора.
  • Проверете пренасочванията. Браузърът може да получава отговор от различен URL или произход след пренасочване.
  • Проверете поведението на прокси/CDN. Nginx, gateway, serverless платформа или CDN могат да добавят, премахнат, дублират или заменят заглавни редове.
  • Проверете отговорите при грешка. Нормален отговор 200 може да съдържа CORS заглавни редове, докато отговор 401, 404 или 500 не ги съдържа.
  • Проверете буквалния произход. Схемата, името на хоста и портът имат значение; localhost и 127.0.0.1 не са взаимозаменяеми за съвпадение на CORS.
  • Проверете за дублиращи се заглавни редове. MDN документира, че множество Access-Control-Allow-Origin заглавни редове не са разрешени. Вижте MDN за множество Access-Control-Allow-Origin заглавни редове.

Ръчни заглавни редове срещу cors middleware

Можете да зададете CORS заглавни редове ръчно с API за отговор на Express, но е лесно да пропуснете поведението при preflight, правилата за удостоверяващи данни, динамичното съвпадение на произхода, Vary: Origin или пътищата при грешка. Официалният cors middleware вече предлага опции за origin, методи, разрешени заглавни редове, изложени заглавни редове, удостоверяващи данни, поведение при preflight и максимална възраст (max age). За повечето Express проекти използването на това middleware държи политиката ясна и по-лесна за преглед.

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

Практически чеклист за производство

  • Избройте точните произходи на фронтенда, които трябва да могат да четат API.
  • Използвайте HTTPS произходи в производство и дръжте произходите за разработка отделни.
  • Инсталирайте CORS middleware преди защитените API маршрути, които имат нужда от него.
  • Използвайте конкретни произходи за частни или удостоверяващи крайни точки.
  • Проверете както нормалните отговори, така и отговорите на предварителни заявки OPTIONS в браузъра.
  • Проверете пътищата при грешка, като отговори 401, 404 и 500, ако те могат да бъдат върнати между различни произходи.
  • Третирайте CORS като политика за четене на браузъра, а не като удостоверяване или упълномощаване.

В илюстративния сценарий с таблица за задачи, трайното решение е просто: идентифицирайте точния произход на фронтенда, конфигурирайте Express да връща съвпадащия CORS заглавен ред, оставете middleware на ниво приложение да обработи preflight и проверете заглавните редове в отговора, който браузърът всъщност получава. Ако заглавният ред все още липсва след това, следващият заподозрян обикновено е редът на middleware или инфраструктурата между браузъра и Express, а не самата fetch заявка на фронтенда.

Официални препратки

Оставете коментар

Как да поправите грешката Uncaught ReferenceError: process is not defined във Vite

Как да поправите грешката Uncaught ReferenceError: process is not defined във Vite

Поправете грешката "process is not defined" във Vite, като замените използването на process.env в стил Node.js, конфигурирате правилно променливите с префикс VITE_ и проверите зависимостите.

Как да поправите грешката „PyTorch CUDA Out of Memory“ по време на обучение на модел

Как да поправите грешката „PyTorch CUDA Out of Memory“ по време на обучение на модел

Поправете грешките за липса на памет в PyTorch CUDA с практичен работен процес: измерете паметта на GPU, намалете работния набор, използвайте AMP и акумулиране на градиенти, създайте контролни точки на активациите и настройте аллокатора само когато е необходимо.

Как да поправите липсващия CORS заглавен ред Access-Control-Allow-Origin в Express.js

Как да поправите липсващия CORS заглавен ред Access-Control-Allow-Origin в Express.js

Поправете грешката за липсващ Access-Control-Allow-Origin CORS в Express.js, като диагностицирате произхода, конфигурирате cors безопасно, обработвате предварителните заявки (preflight) и проверявате заглавните редове.

Как да поправите грешката „Cannot read properties of undefined (reading 'map')“ в React

Как да поправите грешката „Cannot read properties of undefined (reading 'map')“ в React

Поправете грешката на React „Cannot read properties of undefined (reading 'map')“, като проследите undefined стойността, коригирате състоянието и данните от API и добавите безопасни предпазители при рендиране.

Как да поправите грешката „Module Not Found: Can’t Resolve fs“ в Webpack

Как да поправите грешката „Module Not Found: Can’t Resolve fs“ в Webpack

Поправете грешката на Webpack „Can’t resolve 'fs'“, като изберете правилното решение: преместете кода, предназначен само за Node, от сървърната страна, използвайте зависимост, безопасна за браузър, задайте fs:false само когато е опционално, или задайте правилната цел за Node.

Как да поправите грешката „Supabase API Key Not Found“ в променливите на средата

Как да поправите грешката „Supabase API Key Not Found“ в променливите на средата

Поправете липсващи Supabase API ключове в Next.js, Vite, Node, деплойменти и Edge Functions. Използвайте текущите имена на publishable/secret ключовете, правилните env файлове и безопасни стъпки за проверка.

Как да поправите грешката „Flutter Command Not Found“ в PATH на macOS

Как да поправите грешката „Flutter Command Not Found“ в PATH на macOS

Поправете грешката „flutter: command not found“ на macOS, като локализирате Flutter SDK, добавите папката bin към PATH, презаредите Zsh и проверите настройките.

Как да поправите грешката „Порт 8080 вече се използва“ в терминала на Windows, macOS и Linux

Как да поправите грешката „Порт 8080 вече се използва“ в терминала на Windows, macOS и Linux

Поправете грешката „Порт 8080 вече се използва“, като намерите процеса, който притежава порта, спрете го безопасно, обработете Docker или изберете нов порт.

Как да поправите грешката в Django “ImproperlyConfigured: The SECRET_KEY Setting Must Not Be Empty”

Как да поправите грешката в Django “ImproperlyConfigured: The SECRET_KEY Setting Must Not Be Empty”

Поправете грешката на Django SECRET_KEY must not be empty, като проверите активния модул за настройки, променливите на средата, генерирането на ключ и конфигурацията за продуктивна среда.

Как да поправите грешката „Connection Refused“ на PostgreSQL за localhost порт 5432

Как да поправите грешката „Connection Refused“ на PostgreSQL за localhost порт 5432

Поправете грешката „connection refused“ на localhost:5432, като проверите статуса на сървъра, pg_isready, слушането на порта, postgresql.conf, Docker мапиранията и автентикацията.