При разработке современных веб-приложений, которые взаимодействуют с 1С через HTTP-сервисы, разработчики часто сталкиваются с политикой ограничения одинакового источника (Same-Origin Policy). Когда ваш фронтенд (например, на React, Vue или Angular) находится на одном домене или порту, а база 1С опубликована на другом, браузер блокирует запросы из соображений безопасности. Это и есть классическая проблема CORS (Cross-Origin Resource Sharing). В данной статье мы подробно разберем, как правильно сконфигурировать веб-сервер Apache, чтобы подружить его с запросами к 1С и избавиться от ошибок в консоли браузера.
Чаще всего при попытке обращения к сервису 1С мы видим в консоли разработчика сообщение: Response to preflight request doesn't pass access control check: It does not have HTTP ok status. Давайте проанализируем ситуацию и поймем, что происходит под капотом.
Когда браузер собирается отправить «сложный» запрос (например, POST с типом контента application/json или запрос с использованием авторизации), он сначала отправляет предварительный проверочный запрос методом OPTIONS. Этот запрос называется preflight request. Браузер как бы спрашивает у сервера: «Разрешаешь ли ты домену X отправить мне запрос методом POST с такими-то заголовками?».
Если Apache или модуль расширения 1С настроены на обязательную базовую авторизацию, то этот предварительный запрос OPTIONS натыкается на требование логина и пароля. Но браузер не передает учетные данные в preflight-запросе. В итоге сервер возвращает статус 401 Unauthorized или 405 Method Not Allowed. Браузер видит, что статус ответа не 200 OK, и блокирует основной запрос. Именно эту проблему нам предстоит решить в первую очередь.
Для управления заголовками в Apache используется модуль mod_headers. Прежде всего, убедимся, что он включен в вашем файле httpd.conf. Найдите и раскомментируйте (уберите символ #) следующую строку:
LoadModule headers_module modules/mod_headers.so
После активации модуля мы можем добавлять необходимые инструкции. Рассмотрим базовый вариант настройки, который часто применяется для тестирования, когда мы разрешаем доступ всем источникам. Разберем по шагам добавление кода в блок конфигурации директории или в конец файла httpd.conf:
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
</IfModule>
Обратите внимание на использование директивы always. В Apache есть важное различие между Header set и Header always set. Обычный set работает только для успешных ответов (коды 2xx). Однако 1С может вернуть ошибку или требование авторизации (4xx). Чтобы заголовки CORS присутствовали в ответе сервера даже при ошибках, мы обязательно используем always.
Как мы уже выяснили, просто добавить заголовки часто недостаточно, так как 1С перехватывает запрос и требует авторизацию. Чтобы Apache отвечал «ОК» на предварительные запросы без участия модуля 1С, нам поможет модуль mod_rewrite. Рассмотрим подробнее, как принудительно возвращать статус 200 для метода OPTIONS.
Добавьте следующие строки в конфигурацию вашей публикации (внутри тега <Directory> или в файл .htaccess, если он поддерживается):
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
Что здесь происходит? Мы проверяем: если метод запроса — OPTIONS, то мы немедленно завершаем обработку и возвращаем статус 200 OK. Благодаря этому браузер получает подтверждение, что сервер готов принимать запросы, и следом отправляет основной GET или POST с данными авторизации, который уже успешно обрабатывается модулем 1С.
Проанализируем ситуацию, когда ваш сервис 1С требует авторизацию (Base Auth). В этом случае стандартная настройка со «звездочкой» Access-Control-Allow-Origin "*" работать не будет — современные браузеры считают это небезопасным при передаче учетных данных.
Для корректной работы с авторизацией необходимо выполнить три условия:
"*" в заголовке Access-Control-Allow-Origin укажите конкретный протокол и домен вашего сайта, например: "https://my-app.com".Header always set Access-Control-Allow-Credentials "true".Access-Control-Allow-Headers присутствует заголовок Authorization.Пример расширенной настройки для работы с авторизацией:
<IfModule mod_headers.c>
SetEnvIf Origin "^(https?://(?:.+\.)?my-domain\.ru(?::\d{1,5})?)$" CORS_ALLOW_ORIGIN=$1
Header always set Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "Authorization, Content-Type, Origin, Accept"
</IfModule>
При публикации базы 1С через конфигуратор или утилиту webinst создается файл default.vrd. Иногда настройки, прописанные в httpd.conf, могут конфликтовать с тем, как модуль 1С обрабатывает запросы. Выясним, как минимизировать конфликты.
Рекомендуется прописывать настройки CORS не глобально для всего сервера Apache, а внутри блока <Directory>, который указывает на путь к вашей публикации. В Windows это обычно путь вида "C:/inetpub/wwwroot/my_base". Это гарантирует, что правила применятся именно к конкретному HTTP-сервису 1С.
Также проверьте порядок загрузки модулей. В файле httpd.conf модуль mod_headers должен загружаться раньше, чем модуль 1С (который называется _1cws_module). Если 1С загрузится раньше, она может «захватить» поток вывода и не дать Apache добавить заголовки в конец ответа.
После внесения любых изменений в httpd.conf обязательно перезапустите службу Apache. Чтобы убедиться, что всё настроено верно, воспользуйтесь инструментами разработчика в браузере (клавиша F12, вкладка Network или Сеть):
OPTIONS.200 OK.Access-Control-Allow-Origin и других параметров, которые мы настраивали.mod_headers не активен, либо блок <Directory> указан неверно.Если вы видите, что preflight-запрос проходит успешно (200 OK), но основной запрос (например, POST) падает с ошибкой 401, значит проблема уже не в CORS, а в самой авторизации 1С. В этом случае проверьте правильность передачи заголовка Authorization в вашем коде на стороне клиента (JavaScript). Помните, что при использовании withCredentials: true в XMLHttpRequest или fetch, сервер обязан возвращать конкретный домен в Access-Control-Allow-Origin, а не звездочку.
Следуя этим шагам, мы сможем создать надежную и безопасную конфигурацию Apache для работы с любыми внешними потребителями ваших HTTP-сервисов 1С.