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 — это открывает дыры в безопасности, которые сложно отследить.

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

    Комментарии

    0

    Постройте личный план изучения TypeScript с нуля - полный курс и паттерны проектирования до уровня Middle — бесплатно!

    TypeScript с нуля - полный курс и паттерны проектирования — часть карты развития Frontend, Backend, Mobile

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

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

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

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

    React и Redux Toolkit

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

    Zustand

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

    Neovim

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

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

    Картинка поста Как установить Node.js на Windows: пошаговая инструкция
    Иконка аватараАнтон
    Иконка календаря17 июля 2026
    Node.jsWindowsnpm+ 2juniorИконка уровня junior

    Как установить Node.js на Windows: пошаговая инструкция

    Как установить Node.js на Windows — пошаговая инструкция через официальный установщик и nvm-windows с разбором частых ошибок.

    Иконка чипа0
    Иконка глаза635
    Иконка комментариев0
    Картинка поста CI/CD с GitHub Actions: автоматизация деплоя для начинающих
    Иконка аватараАнтон
    Иконка календаря03 июля 2026
    CI/CDGitHub ActionsDevOps+ 2juniorИконка уровня junior

    CI/CD с GitHub Actions: автоматизация деплоя для начинающих

    CI/CD с GitHub Actions: пошаговая настройка pipeline для автоматического тестирования и деплоя Node.js-приложений без сторонних сервисов.

    Иконка чипа0
    Иконка глаза578
    Иконка комментариев0
    Картинка поста PostgreSQL vs MySQL: что выбрать для проекта
    Иконка аватараАнтон
    Иконка календаря13 августа 2026
    PostgreSQLMySQLбазы данных+ 3middleИконка уровня middle

    PostgreSQL vs MySQL: что выбрать для проекта

    PostgreSQL vs MySQL — сравниваем архитектуру, производительность, типы данных и транзакции, чтобы выбрать подходящую БД для вашего проекта.

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