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

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

    Комментарии

    0

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

    JavaScript с нуля - основы языка и практика для начинающих — часть карты развития Frontend, Backend, Mobile

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

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

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

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

    Продвинутый JavaScript

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

    TypeScript с нуля

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

    Neovim

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

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

    Иконка аватараАнтон
    Иконка календаря27 сентября 2026
    openaiAI-инструментыDevOps+ 2middleИконка уровня middle

    Как установить Codex на Windows в России

    Установка Codex на Windows состоит из двух разных дел, и второе обычно застаёт врасплох. Сам агент ставится одной командой `npm install -g @openai/codex` и на Windows работает так же, как на macOS: пакет скачивается из npm без всяких препятствий. А вот первый же запрос к модели закончится отказом: по умолчанию Codex авторизуется через аккаунт ChatGPT, а этот путь из России закрыт — ни вход, ни оплата подписки российской картой не пройдут. Поэтому после установки нужен второй шаг: прописать Codex другой адрес модельного провайдера и ключ к нему. Ключ можно взять в [AI для кода от PurpleSchool](

    Иконка чипа0
    Иконка глаза17
    Иконка комментариев0
    Иконка аватараАнтон
    Иконка календаря24 сентября 2026
    Claude CodeAnthropicAI-инструменты+ 2middleИконка уровня middle

    Как установить Claude Code на Windows: инструкция из России

    Claude Code ставится на Windows одной командой `npm install -g @anthropic-ai/claude-code` — при условии, что в системе есть Node.js. Проблема начинается после установки: CLI поднимется, но при первом же запросе вернёт ошибку доступа, потому что API Anthropic не обслуживает запросы из России. Поэтому установка на Windows из России — это два отдельных дела: поставить сам пакет и подсунуть ему рабочий адрес API с ключом. Ниже — оба шага по порядку, с синтаксисом именно для PowerShell, а не для bash.

    Иконка чипа0
    Иконка глаза212
    Иконка комментариев0
    Иконка аватараАнтон
    Иконка календаря26 сентября 2026
    Claude CodeAI-инструментыDevOps+ 2middleИконка уровня middle

    Kilo Code в VS Code: установка и настройка из России

    Kilo Code ставится в VS Code из Marketplace за минуту, а спотыкается на следующем шаге: расширению нужен доступ к модели, и штатные способы его получить из России не работают. Рабочая схема выглядит так — поставить расширение, выбрать провайдера Anthropic и подменить ему base URL на прокси, который принимает оплату в рублях. Ниже весь путь целиком: установка, какие поля заполнять в настройках провайдера, как выбрать модель и что проверять, когда агент вместо кода отвечает ошибкой доступа.

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