Совместное использование ресурсов между источниками (CORS) часто может стать камнем преткновения при разработке и развертывании приложений с отдельными серверными и внешними интерфейсами. Эта статья призвана раскрыть тайну этой концепции и представить решение, использующее Nginx в качестве обратного прокси-сервера.
Сказка о двух владениях
Рассмотрим такой сценарий: вы разрабатываете веб-приложение с интерфейсом ReactJS и сервером ExpressJS. Кодовая база организована в виде монорепозитория, что указывает на то, что и внешний, и внутренний код находятся в одном и том же репозитории. Для развертывания вы решаете разместить свой интерфейс на `domainA.com`, а серверную часть на `domainB.com`.
Однако это приводит к проблеме — ваш интерфейс не может общаться с вашим сервером из-за ограничений CORS. Ваш браузер видит домены `domainA.com` и `domainB.com` как отдельные источники и блокирует любые попытки внешнего интерфейса получить ресурсы из внутреннего интерфейса, рассматривая это как потенциальную угрозу безопасности.
Итак, как обойти это, не ставя под угрозу безопасность и не прибегая к «подстановочным» настройкам CORS?
Войдите в Nginx: решение для обратного прокси
Nginx, популярный веб-сервер с открытым исходным кодом, предоставляет мощную функцию, известную как обратное проксирование. Это означает, что Nginx может принимать клиентские запросы и на основе определенных правил перенаправлять эти запросы на соответствующие серверы (в нашем случае на внешний или внутренний сервер).
Используя Nginx в качестве обратного прокси-сервера, вы можете полностью избежать проблем с CORS. Решение включает в себя настройку Nginx для обслуживания вашего интерфейса и сервера из одного домена, что устраняет проблему перекрестного происхождения.
Вот как это работает:
- Внешний интерфейс (ReactJS): настройте Nginx для предоставления внешнего интерфейса непосредственно пользователям, которые посещают `domainA.com`. Это включает в себя хранение статических файлов (HTML, CSS, JavaScript), созданных React, на сервере, где работает Nginx.
- Бэкэнд (ExpressJS): Настройте Nginx для перенаправлять запросы, сделанные на `domainA.com/api`, на ваш внутренний сервер. Независимо от того, находится ли ваш внутренний сервер на том же компьютере или на другом, Nginx будет перенаправлять на него все запросы `/api`.
С точки зрения браузера пользователя , все запросы (как к интерфейсу, так и к серверу) направляются в один и тот же домен (`domainA.com`). Эта настройка устраняет запросы из разных источников, поэтому нет проблем с CORS.
Перенастройка Nginx
Давайте углубимся в практическую сторону вопроса — как настроить Nginx для достижения этой цели? Вот пример конфигурации Nginx:
server { listen 80; server_name domainA.com; location / { # assuming your frontend files are in /var/www/frontend root /var/www/frontend; try_files $uri /index.html; } location /api { # assuming your Express server is running on the same machine # and listening on port 3000, if it's on a different machine # replace 'localhost' with the appropriate IP address proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }
Блок `location/` предназначен для вашего внешнего интерфейса. Он обслуживает файлы из каталога `/var/www/frontend`. Блок `location /api` предназначен для вашего бэкенда. Он перенаправляет запросы на сервер ExpressJS, работающий по адресу `http://localhost:3000`.
Путь Монорепо
Монорепозиторий (сокращение от монолитный репозиторий) — это
стратегия разработки программного обеспечения, при которой код для многих проектов хранится в одном репозитории. Он популярен в крупномасштабных проектах, поскольку упрощает обмен кодом и управление зависимостями.
Хотя монорепозиторий не диктует, как вы должны развертывать свои приложения, он оптимизирует ваш рабочий процесс. Он централизует источник достоверной информации и упрощает многие аспекты управления проектами.
С приведенной выше конфигурацией развертывание становится простым — и интерфейсом, и сервером можно управлять с одного и того же сервера с помощью Nginx, что снижает сложность и сохраняет вашу кодовую базу в чистоте и порядке.
Вынос
CORS — необходимая, но часто сложная часть веб-разработки. Используя возможности Nginx в качестве обратного прокси-сервера, вы можете более легко создавать и развертывать свои приложения, устраняя проблемы CORS и сохраняя при этом хорошо структурированную кодовую базу в монорепозитории. Помните, ключ в том, чтобы иметь единый источник для вашего интерфейса и сервера — все под эгидой одного и того же домена.
Примечание. В этом руководстве предполагается, что вы уже знакомы с Nginx. Если вам неудобно настраивать его самостоятельно, рассмотрите возможность работы с инженером DevOps или кем-то с соответствующим опытом. Крайне важно правильно настроить сервер, чтобы избежать потенциальных проблем с безопасностью и производительностью.