PurpleSchool — курсы программирования онлайн
  • Пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • AI для кодаНовое
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Что такое CORS и как его настроить: полное руководство

    Что такое CORS и как его настроить: полное руководство

    Аватар автора Что такое CORS и как его настроить: полное руководство

    Антон Ларичев

    Иконка календаря29 июня 2026
    CORSHTTPбраузерNode.jsбезопасностьjuniorИконка уровня junior
    Картинка поста Что такое CORS и как его настроить: полное руководство

    Введение

    CORS (Cross-Origin Resource Sharing) — механизм безопасности, встроенный в каждый современный браузер. Он ограничивает HTTP-запросы между разными источниками. Источник (origin) — это комбинация протокола, домена и порта. Например, https://example.com:443 и https://api.example.com:443 — разные источники, даже если домен отличается только поддоменом.

    Когда ваш фронтенд на http://localhost:3000 делает запрос к API на http://localhost:8000, браузер блокирует его по умолчанию. Именно это и называют ошибкой CORS. Разберём, как браузер принимает решение и как разрешить ситуацию на стороне сервера.

    Как браузер проверяет CORS

    Браузер делит запросы на два типа: простые и сложные (preflight).

    Простые запросы

    Запрос считается простым, если используется метод GET, POST или HEAD, а заголовок Content-Type имеет значение text/plain, multipart/form-data или application/x-www-form-urlencoded.

    Для простых запросов браузер сразу отправляет запрос и проверяет заголовок Access-Control-Allow-Origin в ответе:

    GET /api/users HTTP/1.1
    Origin: http://localhost:3000
    Host: api.example.com
    

    Если сервер вернул правильный заголовок, браузер пропустит ответ в JavaScript-код:

    HTTP/1.1 200 OK
    Access-Control-Allow-Origin: http://localhost:3000
    Content-Type: application/json
    

    Preflight-запросы

    Если запрос не простой — например, метод DELETE или присутствует заголовок Authorization — браузер сначала отправляет preflight-запрос методом OPTIONS:

    OPTIONS /api/users HTTP/1.1
    Origin: http://localhost:3000
    Access-Control-Request-Method: DELETE
    Access-Control-Request-Headers: Authorization, Content-Type
    

    Сервер должен ответить с разрешёнными методами и заголовками:

    HTTP/1.1 204 No Content
    Access-Control-Allow-Origin: http://localhost:3000
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE
    Access-Control-Allow-Headers: Authorization, Content-Type
    Access-Control-Max-Age: 86400
    

    Заголовок Access-Control-Max-Age указывает браузеру, сколько секунд кешировать результат preflight — это снижает количество лишних запросов.

    Настройка CORS в Express.js

    Самый простой способ настроить CORS в Node.js — использовать пакет cors.

    npm install cors
    

    Разрешить все источники

    const express = require('express');
    const cors = require('cors');
    
    const app = express();
    
    // Разрешаем все источники — только для локальной разработки
    app.use(cors());
    

    Такая настройка добавляет Access-Control-Allow-Origin: * ко всем ответам. В продакшне это небезопасно.

    Настройка для конкретных источников

    const corsOptions = {
      // Список разрешённых источников
      origin: ['https://example.com', 'https://www.example.com'],
      // Разрешённые HTTP-методы
      methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
      // Разрешённые заголовки в запросе
      allowedHeaders: ['Content-Type', 'Authorization'],
      // Разрешаем передачу куки и заголовка Authorization
      credentials: true,
      // Кешируем preflight на 24 часа
      maxAge: 86400,
    };
    
    app.use(cors(corsOptions));
    

    Динамическое разрешение источников

    Если список источников хранится в базе данных или меняется в рантайме:

    const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
    
    const corsOptions = {
      origin: function (origin, callback) {
        // Разрешаем запросы без origin (например, из Postman)
        if (!origin) return callback(null, true);
    
        if (allowedOrigins.includes(origin)) {
          callback(null, true);
        } else {
          callback(new Error('Источник не разрешён политикой CORS'));
        }
      },
      credentials: true,
    };
    
    app.use(cors(corsOptions));
    

    Настройка CORS в Next.js

    В Next.js CORS удобнее всего настраивать через middleware — это позволяет применить политику сразу ко всем API-маршрутам.

    Через middleware

    // middleware.ts
    import { NextResponse } from 'next/server';
    import type { NextRequest } from 'next/server';
    
    export function middleware(request: NextRequest) {
      const response = NextResponse.next();
    
      response.headers.set('Access-Control-Allow-Origin', 'https://example.com');
      response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
      response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    
      // Preflight-запрос должен вернуться немедленно, без бизнес-логики
      if (request.method === 'OPTIONS') {
        return new NextResponse(null, { status: 204, headers: response.headers });
      }
    
      return response;
    }
    
    export const config = {
      matcher: '/api/:path*',
    };
    

    В отдельном API Route (App Router)

    Если нужно задать CORS только для одного маршрута:

    // app/api/users/route.ts
    import { NextResponse } from 'next/server';
    
    const corsHeaders = {
      'Access-Control-Allow-Origin': 'https://example.com',
      'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    };
    
    // Обязательный обработчик preflight
    export async function OPTIONS() {
      return NextResponse.json({}, { headers: corsHeaders });
    }
    
    export async function GET() {
      const users = [{ id: 1, name: 'Иван' }];
      return NextResponse.json(users, { headers: corsHeaders });
    }
    

    Частые ошибки

    Wildcard с credentials

    Нельзя одновременно использовать Access-Control-Allow-Origin: * и Access-Control-Allow-Credentials: true — браузер явно запрещает такую комбинацию.

    Неправильно:

    Access-Control-Allow-Origin: *
    Access-Control-Allow-Credentials: true
    

    Правильно:

    Access-Control-Allow-Origin: https://example.com
    Access-Control-Allow-Credentials: true
    

    Не обрабатывается OPTIONS

    Если сервер возвращает 404 или 405 на OPTIONS-запрос, preflight проваливается и браузер блокирует основной запрос. Убедитесь, что middleware или роутер обрабатывает OPTIONS для всех защищённых маршрутов.

    Дублирование заголовков

    Если CORS настроен и в middleware, и в обработчике маршрута, заголовок Access-Control-Allow-Origin дублируется. Браузер считает такой ответ некорректным и блокирует его. Настраивайте CORS в одном месте.

    CORS не заменяет авторизацию

    CORS — ограничение браузера, не защита сервера. curl и Postman игнорируют CORS. Всегда проверяйте токены и права доступа на стороне сервера, независимо от настроек CORS.

    Заключение

    CORS — это не баг и не случайность, а намеренный защитный механизм браузера. Понимание разницы между простыми и preflight-запросами позволяет быстро диагностировать ошибки и точно настраивать заголовки.

    Для большинства проектов достаточно пакета cors в Express или middleware в Next.js с явным списком разрешённых источников. Избегайте wildcard * в продакшне, особенно если используете cookies или заголовок Authorization — это открывает дыры в безопасности, которые сложно отследить.

    Иконка глаза2

    Комментарии

    0

    Постройте личный план изучения Vue.js 3, Vue Router и Pinia до уровня Middle — бесплатно!

    Vue.js 3, Vue Router и Pinia — часть карты развития Frontend

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    Angular

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Гарантия
    Бонусы
    иконка звёздочки рейтинга5.0
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Nuxt

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга5.0
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Feature-Sliced Design

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.5
    3 999 ₽ 6 990 ₽
    Подробнее

    Похожие статьи

    Картинка поста HTTP методы GET POST PUT DELETE: разница и применение
    Иконка аватараАнтон
    Иконка календаря27 июня 2026
    HTTPRESTAPI+ 2juniorИконка уровня junior

    HTTP методы GET POST PUT DELETE: разница и применение

    HTTP методы GET, POST, PUT, DELETE — основа любого REST API. Разбираем, чем они отличаются, когда применять каждый и какие ошибки допускают новички.

    Иконка чипа0
    Иконка глаза76
    Иконка комментариев0
    Картинка поста Что такое REST API и как его правильно проектировать
    Иконка аватараАнтон
    Иконка календаря22 июня 2026
    REST APIHTTPbackend+ 2juniorИконка уровня junior

    Что такое REST API и как его правильно проектировать

    REST API — архитектурный стиль для взаимодействия клиента и сервера. Разбираем принципы REST, HTTP-методы, проектирование маршрутов и типичные ошибки.

    Иконка чипа0
    Иконка глаза129
    Иконка комментариев0
    Картинка поста Авторизация и аутентификация в Node.js: JWT, OAuth2 и сессии
    Иконка аватараАнтон
    Иконка календаря11 июня 2026
    Node.jsБезопасностьJWT+ 2middleИконка уровня middle

    Авторизация и аутентификация в Node.js: JWT, OAuth2 и сессии

    Авторизация и аутентификация на Node.js: разбираем JWT, OAuth2 и серверные сессии с примерами кода на Express и рекомендациями по безопасности.

    Иконка чипа0
    Иконка глаза548
    Иконка комментариев0
    Иконка чипа0