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

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

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • Подписка
    • 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 — это открывает дыры в безопасности, которые сложно отследить.

    Иконка глаза1 159

    Комментарии

    0
    Бесплатный курс

    Учитесь программировать с AI-агентом — бесплатно

    Курс «AI в обучении: OpenCode и skills»: поставите агента и разберёте с ним любую тему — как эту статью.

    opencode

    >объясни этот код и дай задачу

    ◆Читаю src/server.ts…

    ✓Разбор готов: 4 шага

    ✓Задача → practice/01.md

    • Установка и настройка OpenCode
    • Агент и skills на практике
    • 13 уроков, 3 модуля
    Начать бесплатно

    0 ₽ · доступ сразу после регистрации

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

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

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

    Основы Git

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

    HTML и CSS

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

    CSS Flexbox

    Антон Ларичев
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.9
    бесплатно
    Подробнее

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

    Картинка поста API-ключ OpenAI в России: как получить и чем заменить
    Иконка аватараАнтон
    Иконка календаря11 ноября 2026
    OpenAIAPI-ключAI-инструментыjuniorИконка уровня junior

    API-ключ OpenAI в России: как получить и чем заменить

    Почему API-ключ OpenAI нельзя получить из России и как подключить GPT через совместимый ключ: Python, Node.js, curl и стриминг.

    Иконка чипа0
    Иконка глаза23
    Иконка комментариев0
    Картинка поста Claude Code по API-ключу вместо подписки: настройка
    Иконка аватараАнтон
    Иконка календаря10 ноября 2026
    Claude CodeAnthropicAI-инструментыjuniorИконка уровня junior

    Claude Code по API-ключу вместо подписки: настройка

    Как подключить Claude Code по API-ключу вместо подписки: переменные, проверка через /status, приоритет ключа и частые ошибки.

    Иконка чипа0
    Иконка глаза325
    Иконка комментариев0
    Картинка поста Обучение Claude Code: с чего начать, курсы и материалы
    Иконка аватараАнтон
    Иконка календаря09 ноября 2026
    AI-инструментыClaude CodeразработкаjuniorИконка уровня junior

    Обучение Claude Code: с чего начать, курсы и материалы

    С чего начать обучение Claude Code: план на первую неделю, порядок тем, бесплатные материалы, курсы и как получить доступ для практики из России.

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