n8n webhook работает при тестировании, но не принимает заявки с сайта

В редакторе n8n вы нажимаете «Listen for test event», отправляете форму — данные приходят. Закрываете редактор, и заявки с сайта перестают поступать. Сначала проверьте три вещи: сайт действительно вызывает Production URL, нужная версия сценария (workflow) опубликована, а HTTP-метод запроса совпадает с настройкой Webhook. Если это выполнено, сравните запрос с сайта с прямым запросом через curl и найдите место, где они начинают отличаться.

Ниже — порядок проверки обычного узла Webhook, который принимает данные внешней формы. Он подходит для n8n Cloud и самостоятельной установки; раздел с Docker и обратным прокси нужен только владельцам своего сервера. У Form Trigger, Telegram Trigger и других специализированных триггеров есть дополнительные особенности.

Проверьте рабочий адрес и опубликованную версию

У Webhook два адреса. При стандартной конфигурации они выглядят так:

Тестовый: https://automation.example.com/webhook-test/site-lead
Рабочий:  https://automation.example.com/webhook/site-lead

Тестовый адрес предназначен для временного ожидания запроса после запуска теста. Для постоянного приёма заявок нужен рабочий адрес и опубликованный workflow. Само переключение вкладки с Test URL на Production URL только показывает другой адрес.

  1. Откройте Webhook и проверьте HTTP Method и Path. Для формы, отправляющей POST, узел тоже должен принимать POST.
  2. Опубликуйте нужную версию через Publish и дождитесь завершения публикации. Если интерфейс показывает ошибку или частичную публикацию, откройте её подробности: нужный триггер мог не зарегистрироваться. В старых версиях интерфейса используется переключатель Active.
  3. Скопируйте Production URL прямо из узла и замените адрес в интеграции сайта. Если URL хранится в переменной сборки клиентской части сайта, пересоберите и разверните сайт.
  4. Отправьте новую тестовую заявку и откройте вкладку Executions. Рабочие вызовы не показывают прохождение узлов в редакторе так, как это происходит при ручном тесте.

В текущем интерфейсе сохранение изменений и публикация — разные действия. Исправленный Path, метод или обработка данных могут оставаться в черновике, пока рабочие запросы используют прежнюю опубликованную версию.

Если публикация сообщает о конфликте, найдите другой workflow с той же комбинацией пути и HTTP-метода. Определите, какой сценарий должен обслуживать этот адрес. Для новой интеграции задайте отдельный Path; отключать чужой рабочий сценарий ради проверки не нужно.

Посмотрите, что сайт отправляет на самом деле

Откройте инструменты разработчика браузера, вкладку Network, включите Preserve log и один раз отправьте форму. Используйте вымышленные контактные данные и уникальную метку, например diag-20261008-01. Учтите, что такая отправка может создать запись в CRM или запустить уведомление.

У запроса проверьте:

  • Request URL: домен, HTTPS, полный путь, отсутствие webhook-test, лишних пробелов и переноса строки.
  • Request Method: POST или другой метод, который настроен в узле.
  • Payload и Content-Type: какие поля реально отправились и в каком формате.
  • Status и Response: код ответа и его содержимое. Сохраните также время запроса и часовой пояс.

Если форма сначала обращается к обработчику сайта, например /api/contact, браузер покажет только этот запрос. Вызов n8n делает уже сервер сайта: его адрес, ответ и ошибку нужно искать в журнале обработчика или плагина интеграции. Успешный ответ сайта сам по себе не подтверждает доставку в n8n.

Если сетевого запроса вообще нет, откройте Console. Ошибка JavaScript, проверка обязательных полей, блокировка смешанного HTTP/HTTPS-контента или политика безопасности контента (CSP) могут остановить отправку ещё в браузере. Исправляйте указанную причину и повторяйте проверку Network.

Открытие webhook в адресной строке браузера отправляет GET. Ошибка такого запроса ничего не говорит о работоспособности узла, настроенного на POST.

Отделите проблему сайта от проблемы webhook

Выполните запрос с компьютера вне сервера n8n. Пример ниже рассчитан на POST с JSON; замените адрес и поля на свои. Для проверки используйте отдельную тестовую заявку, которую можно безопасно обработать.

curl -i --connect-timeout 10 --max-time 30 \
  --request POST \
  'https://automation.example.com/webhook/site-lead' \
  --header 'Content-Type: application/json' \
  --data '{"lead_id":"diag-20261008-02","name":"Проверка","email":"test@example.com"}'

Если Webhook защищён авторизацией, запрос должен передавать соответствующие учётные данные. Например, при Header Auth добавьте настроенный заголовок через --header 'X-Webhook-Token: ВАШ_ТОКЕН', заменив и имя, и значение на свои. Не отключайте авторизацию для устранения 401 и не публикуйте команду с настоящим секретом.

Сравнивайте одинаковые запросы: успешный GET без данных не проверяет POST с JSON. curl также не применяет браузерные ограничения CORS, поэтому его успех ещё не доказывает, что JavaScript сайта сможет прочитать ответ.

Результат Что это означает Следующий шаг
404 с JSON n8n и текстом webhook ... is not registered Обработчик n8n не нашёл регистрацию для полученных метода и пути. Сверьте метод, полный URL, публикацию и маршрут до нужного экземпляра n8n.
404 с HTML-страницей сайта, прокси или панели Запрос мог попасть в другой виртуальный хост или обработчик. Сопоставьте ответ с журналом прокси и адресом upstream — сервиса, которому прокси передаёт запрос.
301 или 302 Адрес перенаправляет запрос. Посмотрите заголовок Location и настройте сайт на конечный HTTPS-адрес. Затем проверьте, что до n8n доходит нужный метод и тело.
401 или 403 Запрос отклоняет авторизация, список разрешённых IP или защита перед n8n. Проверьте Authentication и IP(s) Allowlist в Webhook, затем правила прокси/CDN. Вход в редактор n8n не авторизует запрос формы автоматически.
2xx, но записи в CRM нет HTTP-запрос получил успешный ответ; результат обработки заявки ещё неизвестен. Найдите соответствующее выполнение и проверьте узел сохранения данных.
502, 504 или тайм-аут Прокси не получил нормальный ответ либо обработка заняла слишком много времени. Проверьте доступность n8n, журнал прокси и длительность выполнения. Перед повтором выясните, не была ли заявка уже сохранена.

Если curl не получает HTTP-ответ из-за ошибки DNS, сертификата или соединения, сначала исправьте доступность публичного домена и HTTPS. Не скрывайте ошибку сертификата параметром -k  сайт продолжит сталкиваться с ней.

Когда curl создаёт выполнение, а форма — нет, сравните фактический запрос формы с этой командой. Если нужно, воспользуйтесь Copy as cURL в Network, предварительно учитывая, что повтор команды повторно отправит заявку. Не передавайте скопированные cookies, токены и персональные данные в публичные обсуждения.

Если curl работает, а браузер сообщает о CORS

CORS — механизм, который регулирует доступ JavaScript к ответам другого источника. Например, страница https://www.example.com обращается к https://automation.example.com. При отправке JSON браузер обычно сначала делает проверочный запрос OPTIONS, а после разрешения отправляет POST.

В Network различайте два случая. Если OPTIONS завершается ошибкой и POST отсутствует, данные ещё не отправлены. Если POST уже есть, а браузер блокирует чтение ответа, workflow мог выполниться. Проверьте Executions до повторной отправки.

  1. В Webhook откройте Parameters → Add Option → Allowed Origins (CORS). Укажите точный источник сайта, например https://www.example.com, без пути и завершающего слеша. Для нескольких источников используйте список через запятую без пробелов; учитывайте различие адресов с www и без него.
  2. Опубликуйте изменение и проверьте, что прокси пропускает OPTIONS к этому адресу. Не заменяйте POST на OPTIONS в самом Webhook.
  3. Посмотрите заголовки ответа на OPTIONS и POST. Не добавляйте одинаковый Access-Control-Allow-Origin одновременно в n8n и прокси: несколько значений этого заголовка браузер отвергает.

Проверочный запрос для примера с JSON:

curl -i --request OPTIONS \
  'https://automation.example.com/webhook/site-lead' \
  --header 'Origin: https://www.example.com' \
  --header 'Access-Control-Request-Method: POST' \
  --header 'Access-Control-Request-Headers: content-type'

Ожидается успешный ответ, обычно 204, с разрешённым источником https://www.example.com, методом POST в Access-Control-Allow-Methods и заголовком content-type в Access-Control-Allow-Headers. Если сайт отправляет дополнительные заголовки, проверяйте и их. Перенаправление OPTIONS на страницу входа или HTML-проверка CDN означают, что запрос перехватывается перед n8n.

mode: "no-cors" не исправляет интеграцию: JavaScript теряет возможность нормально читать ответ. CORS также не заменяет авторизацию и не защищает публичную форму от отправки запросов через curl.

Если для вызова n8n нужен постоянный секрет, храните его в серверном обработчике сайта. Браузер отправляет форму своему серверу, а тот проверяет данные и вызывает n8n с Header Auth. Секрет, встроенный в публичный JavaScript, доступен посетителям.

Что проверить на VPS - адрес, прокси и процессы n8n

Этот раздел нужен, если прямой вызов Production URL тоже не работает. Для Docker Compose выполняйте команды из каталога существующего проекта, с теми же Compose-файлами и параметрами, с которыми он запущен. Ниже сервис называется n8n; своё имя найдите первой командой.

docker compose config --services
docker compose ps
docker compose exec -T n8n n8n --version
docker compose logs --since=15m --tail=200 n8n

Сопоставьте время контрольного запроса с ошибками регистрации webhook и состоянием контейнера. Если контейнер перезапускается или не запущен, сначала выясните причину по его журналу.

Проверьте выбранные переменные именно внутри запущенного контейнера:

docker compose exec -T n8n env | grep -E '^(N8N_WEBHOOK_URL|WEBHOOK_URL|N8N_PROXY_HOPS|N8N_DISABLE_PRODUCTION_MAIN_PROCESS|EXECUTIONS_MODE)='

В документации n8n для внешнего адреса используется N8N_WEBHOOK_URL. Начиная с n8n 2.35.0 прежнее имя WEBHOOK_URL объявлено устаревшим, но продолжает работать как совместимый вариант. В более старых установках используйте поддерживаемое ими имя WEBHOOK_URL. Не задавайте этим переменным разные адреса.

Для n8n 2.35.0 и новее, размещённого в корне отдельного домена за одним обратным прокси, пример значений такой:

N8N_WEBHOOK_URL=https://automation.example.com/
N8N_PROXY_HOPS=1

Здесь указан базовый публичный адрес, без /webhook/site-lead. Значение 1 подходит для одного доверенного прокси; при цепочке CDN → прокси → n8n учитывайте фактическую схему. Последний прокси должен корректно передавать X-Forwarded-For, X-Forwarded-Host и X-Forwarded-Proto.

Правильная переменная адреса не создаёт маршрут в прокси. Если используется Nginx, проверьте location и proxy_pass. Например, в блоке location /webhook/ значение proxy_pass http://n8n:5678/; заменяет совпавшую часть пути на /. При стандартных маршрутах n8n это может отправить /site-lead вместо /webhook/site-lead. Вариант без URI, proxy_pass http://n8n:5678;, сохраняет исходный путь. Имя n8n здесь условное: оно должно разрешаться из окружения самого Nginx.

Проверяйте соответствующий access/error log прокси: к какому сервису ушёл запрос, какой путь был передан и какой ответ вернул upstream. При специальных rewrite-правилах ориентируйтесь на итоговый путь, который получает n8n. После правки проверьте синтаксис через nginx -t в окружении, где запущен Nginx; при успешной проверке перечитайте конфигурацию через nginx -s reload с необходимыми правами. Затем повторите контрольный запрос.

Есть отдельная причина, особенно точно совпадающая с симптомом «тест работает, production нет»: N8N_DISABLE_PRODUCTION_MAIN_PROCESS=true отключает рабочие webhook на основном процессе. В установке с одним процессом, который должен принимать заявки, эту настройку нужно убрать или установить в false. При выделенных webhook-процессах она может быть правильной: тогда /webhook/* направляют на них, а /webhook-test/* — на основной процесс. Worker исполняет задания из очереди и не заменяет webhook-процесс.

Перед изменением конфигурации сохраните её прежнюю копию и запланируйте короткую паузу приёма заявок. Если у сайта нет собственного сохранения или очереди отправки, на время перезапуска приостановите форму с понятным сообщением о перерыве. В Compose изменение environment применяется пересозданием контейнера, например docker compose up -d --no-deps n8n, с прежним зафиксированным образом и существующими томами. Обычный restart новые значения из Compose не подхватит. После применения повторите проверку переменных и контрольный запрос; при ухудшении верните предыдущую конфигурацию и примените её тем же способом. Не удаляйте тома, базу или ключ шифрования ради исправления webhook.

Запрос дошёл, но заявка не сохранилась

Откройте конкретное выполнение в Executions по времени отправки. Если история пуста, проверьте фильтры списка и меню workflow → Settings → Save successful production executions / Save failed production executions. На время диагностики включите сохранение успешных и неуспешных выполнений и отправьте новую тестовую заявку: прежние несохранённые данные не появятся задним числом.

В выполнении откройте Webhook и посмотрите реальные входные данные. При обычном разборе JSON поля тела находятся внутри body. Например, в узле сразу после Webhook адрес из {"email":"test@example.com"} читается как {{ $json.body.email }}. Выражение {{ $json.email }} обращается к другому уровню. Если включён Raw Body или предыдущий узел изменяет структуру данных, ориентируйтесь на фактический output этого узла.

Сравните рабочие данные с тестовыми. Закреплённые через Pin data значения используются при разработке и не подменяют входящие данные в production. Исправьте сопоставление полей, опубликуйте изменения и проверьте свежую отправку.

Затем пройдите до узла создания заявки. Ошибка учётных данных подключения, обязательное поле CRM, ветка IF, которая не пропускает данные, или отсутствие элементов на выходе могут остановить нужное действие. Даже выполнение со статусом Success не доказывает, что сценарий прошёл через узел записи: откройте его результат и найдите созданную запись в самой CRM.

Если в вашей версии у Webhook доступна опция Only Run If, проверьте её условие отдельно. Когда оно возвращает false, n8n может ответить 200, не создавая выполнение. Сравните условие с реальным телом запроса; для воспроизведения используйте отдельный диагностический workflow без этого фильтра.

В queue mode выполнение может оставаться в очереди. Тогда проверяйте состояние workers и их подключение к Redis и общей базе данных. Исправление URL не поможет заданию, которое уже принято и ожидает исполнения.

Возвращайте сайту подтверждение сохранения

Режим Respond → Immediately отвечает до завершения последующих действий. Пользователь может увидеть сообщение об успехе, даже если следующий узел не смог записать заявку.

Для формы, которой нужно подтверждение записи, настройте такую последовательность:

Webhook → Проверка полей → Сохранение заявки → Respond to Webhook
  1. В Webhook выберите Respond → Using 'Respond to Webhook' Node.
  2. На успешной ветке поставьте Respond to Webhook после подтверждённого сохранения.
  3. В ответном узле выберите Respond With → JSON и верните понятный сайту результат, например {"ok":true,"lead_id":"diag-20261008-02"}. Это пример: реальный lead_id должен соответствовать конкретной сохранённой заявке.
  4. Для неверных данных предусмотрите отдельную ветку с ответом 400 и {"ok":false,"error":"invalid_input"}. Ошибка записи не должна попадать на ветку успешного подтверждения.

Проверьте все выходы из условий: если workflow завершится, не выполнив Respond to Webhook, n8n может вернуть стандартный ответ 200. Поэтому код сайта должен проверять и HTTP-статус, и ожидаемый JSON, а не показывать «Отправлено» при любом завершившемся запросе.

Если после записи идут долгие операции — например, запрос к AI или несколько внешних API, — ответьте сразу после надёжного сохранения, а оставшуюся обработку продолжайте отдельно. Для принятия в обработку можно использовать 202. Сообщение пользователю должно соответствовать этому состоянию: заявка принята, дальнейшая операция ещё выполняется.

Не полагайтесь на тайм-аут как на доказательство потери заявки: сервер мог сохранить её, но не успеть вернуть ответ. Перед повтором проверьте запись по идентификатору.

Как убедиться, что заявки больше не теряются

Закройте редактор n8n и отправьте две заявки с сайта с разными идентификаторами. Для каждой должна прослеживаться цепочка: запрос формы → выполнение нужного workflow → запись в целевой системе → корректное сообщение на сайте.

Отдельно отправьте форму с неверными данными: она должна показать понятную ошибку, не создавая заявку с пустыми обязательными полями. Проверьте также повторную отправку одной и той же заявки.

Если интеграция поддерживает повторы, передавайте постоянный lead_id для одной заявки, сохраняйте его при повторных отправках и записывайте вместе с данными. Защиту от дублей обеспечьте уникальным ограничением в базе или документированной операцией upsert — созданием или обновлением записи по уникальному ключу — в целевой системе. Схема «сначала найти, потом создать» без такой гарантии может пропустить два одновременных запроса.

Для последующих сбоев создайте отдельный сценарий Error Trigger → отправка уведомления и выберите его в поле Error Workflow настроек основного workflow. Проверьте уведомление контролируемой ошибкой в отдельной опубликованной копии. Не оставляйте единственным признаком неполадки жалобу посетителя.

Когда передать диагностику администратору

Если правильный Production URL продолжает возвращать 404, создайте отдельный минимальный workflow с уникальным Path: Webhook → Respond to Webhook. Задайте тот же HTTP-метод, настройте ответ по предыдущему разделу, опубликуйте и вызовите напрямую. Успешный ответ сузит поиск до настроек исходного сценария или его адреса; такой же сбой потребует проверки регистрации и инфраструктуры экземпляра.

В n8n Cloud передайте поддержке версию, workflow ID, время запроса с часовым поясом, метод, путь, код и тело ответа, а также результат проверки минимального сценария. По одному 404 нельзя достоверно объявить причиной сбой облачной платформы.

Если n8n работает на вашем VPS и проблема упирается в Docker, HTTPS или маршрутизацию прокси, задачу можно обсудить в рамках администрирования серверов QCKL. Приложите обезличенные результаты проверок; объём работ, стоимость и допустимый перерыв в приёме заявок согласуйте до изменений.

  • 0 Uživatelům pomohlo
Byla tato odpověď nápomocná?

Související články

VGA монитор для серверов в 2026: зачем он всё ещё нужен в дата-центре и что даёт Sceptre 24″ Prime E248W-19203R

VGA давно пропал из мира ноутбуков, мини-ПК и рабочих станций, но в серверной реальности он...

10GbE в 2026 выходит на переломный момент: почему 10Gbase-T становится нормой для серверов

10GbE в 2026 перестал быть «дорогой игрушкой» для энтузиастов и крупных дата-центров. Он быстро...

Сетевая карта 2.5GbE PCIe в 2026: mini-обзор BrosTrend и зачем апгрейд

Если вы всё ещё живёте на 1GbE, то знакомы с ощущением «железо норм, а сеть душит». Копирование...

1, 10, 40 или 100 Gb/s: какой порт нужен серверу под реальную задачу

Скорость порта у выделенного сервера часто выбирают неправильно. Клиент видит 10 Gb/s или 100...

Dedicated server для streaming, CDN и раздачи файлов: почему важны порт, peering и трафик

Dedicated server для streaming, CDN и раздачи файлов выбирают не так, как обычный сервер для...