Пошаговые инструкции Для начинающих 13 мин

Как отправить файл в n8n через HTTP Request

Создайте TXT и отправьте его вместе с номером заявки через multipart/form-data. 12 шагов, две готовые схемы и проверка содержимого на стороне получателя.

n8n HTTP Request Файлы

Файл уже есть в n8n, но внешний API ждёт multipart/form-data: как его отправить вместе с номером заявки? Соберём учебный пример без чужих аккаунтов. Один workflow создаст TXT и отправит его через HTTP Request, второй примет файл и вернёт его текст. В конце проверим совпадение содержимого.

Результат инструкции

Получим ответ status: verified, request_id: demo-001, file_name: note-demo.txt, bytes: 63 и uploaded: true. Это подтверждение учебной передачи между двумя workflow в одном локальном n8n. Ни одно письмо, CRM-действие или внешняя публикация не выполняется; action: false относится именно к этим бизнес-действиям, а сам HTTP-запрос действительно отправляется.

Отправитель использует штатные Convert to File и HTTP Request. Получатель взят из инструкции приёма файла через Webhook, но имеет отдельный путь, чтобы не затронуть прежнюю схему. Все файлы и номера заявок вымышленные. Публичные workflow неактивны.

Что понадобится

  • Локальный n8n. Проверено на 2.42.4: HTTP Request 4.4, Convert to File 1.1, Webhook 2.1 и Code 2.
  • Два новых workflow в одном экземпляре n8n. Для основного примера n8n работает в Docker на внутреннем порту 5678, интерфейс может быть доступен на localhost:5679.
  • Две скачиваемые JSON-схемы из статьи. Ключи нейросетей, платные тарифы, токены чужих API и рабочие документы не нужны.

Установка n8n локально через Docker

Шаг 1. Импортируйте получателя файла

Скачать n8n-http-upload-receiver.json

Создайте новый workflow и через Import from File загрузите n8n-http-upload-receiver.json. Назовите его «Учебный получатель TXT». В нём пять узлов: Upload Request → Check Upload → Read Text → Upload Preview → Send Reply. Не публикуйте его.

Получатель принимает один UTF-8 файл note-demo.txt с MIME text/plain и текстовое поле request_id вида demo-001. Проверяет размер от 1 до 4096 байт, пустой текст, NUL и кодировку. Не меняйте эти проверки для прохождения теста. Это не универсальная загрузка PDF и не антивирус.

Как устроен получатель: файл через Webhook

Шаг 2. Сверьте настройки получателя

Поле Upload Request Значение Проверка
HTTP Method POST Совпадает с отправителем
Path ezgpt-http-upload-receiver Отдельный учебный маршрут
Authentication None, только loopback-тест Не открывать endpoint в сеть
Respond Using Respond to Webhook node Ответ вернёт Send Reply

Options Webhook оставьте по умолчанию, без Raw Body, Binary Property и переименования binary-полей. Файловое поле формы document должно появиться в binary.document, а номер заявки — в body.request_id. Read Text использует Extract From Text File, Input Binary Field: document, Destination Output Field: text, utf8, Strip BOM и Keep Source: JSON.

В Send Reply получателя уже выбраны First Incoming Item, код 200 и Cache-Control: no-store. Сохраните схему. Слушатель пока можно не запускать: сначала подготовим отправителя.

Шаг 3. Импортируйте отправителя

Скачать n8n-http-send-file.json

Создайте второй новый workflow, импортируйте n8n-http-send-file.json и назовите его «Учебная отправка TXT». В нём шесть узлов:

text
Manual Trigger → Sample Note → Make TXT → Check File → Send File → Check Receipt

Sample Note, Check File и Check Receipt — Code; Make TXT — Convert to File; Send File — HTTP Request. Обе схемы должны находиться в одном локальном экземпляре n8n, но не быть объединены проводами или скопированы в рабочую автоматизацию.

Шаг 4. Задайте учебный текст

Откройте Sample Note. Режим — Run Once for All Items, язык JavaScript. Код:

javascript
return [{ json: {
  request_id: 'demo-001',
  text: 'Заявка: demo-001\nНужен учебный расчёт.\n',
} }];

В text две строки и завершающий перевод строки LF. Сочетание \n в строке JavaScript создаёт перевод строки, а не два печатных символа. Не вставляйте вместо примера договор или реквизиты клиента. Основной результат ниже относится к точному тексту из кода: в UTF-8 это 63 байта, не 63 буквы.

Шаг 5. Создайте binary-файл через Convert to File

В Make TXT выберите Operation: Convert to Text File. Проверьте:

Поле Make TXT Значение Результат
Text Input Field text Берётся строка из Sample Note
Put Output File in Field upload Файл появится в binary.upload
File Name note-demo.txt Имя для получателя
Encoding / Add BOM utf8 / выключено Исходные 63 байта без BOM

Важно: в проверенной версии Convert to File возвращает файл, но JSON на его выходе пустой. Поэтому следующий узел явно берёт номер заявки из Sample Note и возвращает его вместе с binary. Не рассчитывайте, что $json.request_id сам сохранится после Make TXT.

Шаг 6. Проверьте байты до отправки

В Check File оставьте Run Once for All Items и JavaScript. При ручной сборке вставьте:

javascript
const items = $input.all();
if (items.length !== 1) throw new Error('Expected one file');
const source = $('Sample Note').first().json;
if (typeof source.request_id !== 'string' || !/^demo-[0-9]{3}$/.test(source.request_id) ||
    typeof source.text !== 'string' || !source.text.trim() || source.text.includes('\u0000')) {
  throw new Error('Invalid sample fields');
}
const item = items[0];
if (Object.keys(item.binary ?? {}).join('|') !== 'upload') {
  throw new Error('Expected binary.upload');
}
const file = item.binary.upload;
if (file.fileName !== 'note-demo.txt' || file.mimeType !== 'text/plain') {
  throw new Error('Expected note-demo.txt with text/plain');
}
const bytes = await this.helpers.getBinaryDataBuffer(0, 'upload');
const expected = Buffer.from(source.text, 'utf8');
if (bytes.length < 1 || bytes.length > 4096 || !bytes.equals(expected)) {
  throw new Error('File bytes differ from the sample');
}
return [{
  json: { request_id: source.request_id, expected_text: source.text, expected_bytes: bytes.length },
  binary: { upload: file },
}];

Код проверяет типы исходных полей, наличие ровно binary.upload, имя, MIME и размер. Сравнивает реальные байты файла с UTF-8 исходной строки. Неверное имя, BOM, UTF-16 и слишком большой файл остановят схему до HTTP Request. Чтение через getBinaryDataBuffer работает и с binary на диске; поле upload.data не нужно декодировать вручную.

После узла есть JSON с request_id, expected_text, expected_bytes и binary.upload. Ссылку на Sample Note не переименовывайте отдельно от самого узла. Пример рассчитан на один item и один файл, а не на массовую рассылку вложений.

Шаг 7. Укажите адрес получателя в HTTP Request

Откройте Send File: Method: POST, Authentication: None. Для двух схем в одном Docker-экземпляре со стандартным внутренним портом URL уже задан:

text
http://127.0.0.1:5678/webhook-test/ezgpt-http-upload-receiver

Это адрес из самого процесса n8n, не из браузера Windows. Если Docker публикует порт 5679:5678, в браузере вы видите localhost:5679, но узел внутри этого же контейнера обращается к 127.0.0.1:5678. Не подставляйте автоматически внешний порт 5679 в HTTP Request.

Если n8n запущен без Docker и сам слушает другой порт, укажите его реальный локальный порт. Схемы в разных контейнерах требуют другого сетевого адреса: 127.0.0.1 там указывает на контейнер отправителя. Такой вариант в этой инструкции не проверялся. Не заменяйте URL произвольным чужим upload-сервисом.

Шаг 8. Добавьте две части формы

В Send File включите Send Body, выберите Body Content Type: Form-Data. В Body Parameters добавьте две отдельные строки:

  • Первая: Parameter Type: Form Data; Name: request_id; Value в режиме Expression: {{ $json.request_id }}.
  • Вторая: Parameter Type: n8n Binary File; Name: document; Input Data Field Name: upload.

Здесь три разных имени. upload — поле, где файл хранится внутри отправителя. document — имя файловой части HTTP-формы, которое ожидает получатель. note-demo.txt — имя самого файла. Значение Input Data Field Name вводится как upload, без $binary, фигурных скобок и .data.

n8n Binary File нужно выбрать именно как Parameter Type внутри Form-Data. Не переключайте весь Body Content Type на n8n Binary File: это отправит сырое тело вместо формы с двумя частями. Обычная строка document: note-demo.txt тоже не передаст файл.

Не задавайте Content-Type вручную и не собирайте multipart строками в Code. HTTP Request сам добавит boundary. В этом учебном запросе нет Authorization и секретных заголовков. Для реального API используйте его документированные credentials и HTTPS.

Шаг 9. Настройте чтение ответа

В Options узла Send File добавьте Response. Выберите Response Format: JSON, включите Include Response Headers and Status, оставьте Never Error выключенным. Теперь результат должен содержать statusCode и body, а не только тело ответа.

В Redirects выключите Follow Redirects: учебный файл не должен молча уйти на другой адрес. Timeout: 15000 мс. Ignore SSL Issues оставьте выключенным, даже если сейчас используется локальный HTTP. Timeout относится к ожиданию начала ответа и не является общей защитой от любых зависаний.

On Error у всех узлов оставьте Stop Workflow; Retry On Fail и автоматические повторы не включайте. При отправке файла в реальный сервис повтор может создать второе вложение. Сначала нужно понимать правила повторов и идемпотентности конкретного API.

Шаг 10. Запустите получателя, затем отправителя

Сохраните оба workflow. Откройте получателя в отдельной вкладке редактора, в Upload Request выберите Test URL и нажмите Listen for test event или Execute workflow. Затем перейдите во вкладку отправителя и выполните workflow целиком от Manual Trigger.

Нельзя запускать только Check Receipt без предыдущих данных. Важно, чтобы в этот момент получатель действительно ожидал запрос. Test URL в проверенном режиме одноразовый: после успешной передачи перед повтором снова включите ожидание. Никакую production-публикацию для примера делать не нужно.

У отправителя должны отработать Make TXT, Check File и Send File. У получателя — вся цепочка до Send Reply. В выходе Send File найдите statusCode: 200 и body с исходным текстом, номером заявки, именем и размером файла.

Шаг 11. Сверьте подтверждение содержимого

Последний узел отправителя Check Receipt уже содержит проверку. Режим Run Once for All Items, JavaScript:

javascript
const response = $input.first().json;
const expected = $('Check File').first().json;
const body = response.body;
if (response.statusCode !== 200 || !body || typeof body !== 'object' || Array.isArray(body)) {
  throw new Error('Expected HTTP 200 with a JSON object');
}
const keys = Object.keys(body).sort().join('|');
if (keys !== 'action|bytes|file_name|request_id|status|text' ||
    body.status !== 'preview' || body.request_id !== expected.request_id ||
    body.file_name !== 'note-demo.txt' || body.bytes !== expected.expected_bytes ||
    body.text !== expected.expected_text || body.action !== false) {
  throw new Error('Receiver did not confirm the exact file');
}
return [{ json: {
  status: 'verified', request_id: body.request_id, file_name: body.file_name,
  bytes: body.bytes, uploaded: true, action: false,
} }];

Он проверяет код 200 и точные поля ответа, сравнивает request_id, имя, размер и текст с данными Check File. Просто зелёный HTTP Request или HTTP 200 без совпадения тела не считается успешной передачей. В результате Check Receipt должен быть один item:

json
{
  "status": "verified",
  "request_id": "demo-001",
  "file_name": "note-demo.txt",
  "bytes": 63,
  "uploaded": true,
  "action": false
}

У получателя откройте Upload Request: в body должен быть request_id, в Binary — document. Read Text должен показать тот же текст. uploaded: true здесь выдаёт наша проверка учебного ответа, а не сторонний сервис: это не гарантия долговременного хранения файла или обработки в CRM.

Шаг 12. Проверьте ошибку имени файлового поля

В Send File временно замените Name у файловой строки с document на file. Input Data Field Name оставьте upload. Снова запустите ожидание получателя и выполните отправителя.

Получатель не должен принять такую форму: Check Upload ждёт document. В нашем тесте он остановился до Send Reply, ответ был 500, Send File отправителя завершился ошибкой, Check Receipt не выдал verified. Деталь отказа смотрите в execution получателя. Это учебная остановка исключением, а не настроенный ответ 422.

Верните Name: document. Снова запустите слушатель и всю схему отправителя: результат verified должен восстановиться. Не включайте Never Error или Continue On Fail, чтобы скрыть ошибку поля.

Если результат отличается

Симптом Что проверить Действие
Connection refused Адрес из процесса n8n В одном Docker использовать внутренний порт
404 POST, путь и ожидание Test URL Запустить слушатель получателя
Нет binary upload Выход Make TXT и имя поля Указать upload в обоих узлах отправителя
500 у получателя Name: document и request_id Сверить части multipart-формы
Ошибка Check Receipt Response: JSON, полный ответ и тело Сверить statusCode, body и исходный текст

Перед отправкой реальных файлов

Не публикуйте получателя с Authentication None. Для внешнего доступа нужны HTTPS, авторизация, входные лимиты и правила доступа к файлам. Наши проверки размера внутри workflow не ограничивают загрузку до её приёма и не заменяют антивирус или разбор формата.

Текст и binary могут оставаться в истории executions обеих схем. Отсутствие записи в бизнес-базу не означает отсутствия хранения. Сначала настройте доступ и сроки хранения, затем подставляйте реальные данные. В статье не проверяются облачный n8n, две разные машины, PDF/OCR, чужие API и сетевые proxy.

Добавить Header Auth для Webhook

Что проверено редакцией

17 октября 2026 года обе скачиваемые схемы проверены на n8n 2.42.4 в отдельном Docker-экземпляре с binary на диске. Все 27 тестов прошли: исходный файл, Unicode, CRLF, другой корректный request_id; пустой текст, неверный ID, поле источника, имя файла, BOM, UTF-16, 4097 байт и NUL; неверные имена multipart и binary, пропущенные части, raw binary и JSON вместо формы, имя файла строкой, лишнее поле, неверный метод и отсутствие слушателя; текстовый ответ, отключённый полный ответ, изменённое тело, статус 201 и Never Error при отказе 500. Успешные запросы подтверждены реальным запуском получателя и точным совпадением текста, размера и ID; ошибки не дают verified. Проверены штатные HTTP Request и Convert to File, а не самодельный multipart. Контейнер слушал только loopback и остановлен, существующие workflows не менялись. Клики редактора, production, Cloud, разные контейнеры и сторонние API не тестировались. Обложка — AI-иллюстрация, не снимок интерфейса.

Частые вопросы

Чем Name отличается от Input Data Field Name?

Name: document — имя части формы для получателя. Input Data Field Name: upload — имя binary-поля внутри отправителя. Это не имя файла note-demo.txt.

Почему не подходит Body Content Type: n8n Binary File?

Так весь запрос становится сырым бинарным телом. Здесь нужны две части multipart: текстовый request_id и файл. Поэтому выбираем Form-Data, а n8n Binary File — типом одной строки.

Почему localhost:5679 открывается в браузере, но узел не подключается?

В Docker опубликованный порт хоста и внутренний порт контейнера различаются. Для двух схем в одном стандартном контейнере узел обращается к 127.0.0.1:5678.

Почему после Convert to File пропал request_id?

В проверенной версии текстовая операция возвращает binary и пустой JSON. Check File явно восстанавливает номер из Sample Note и передаёт его дальше.

Можно заменить получателя реальным upload API?

Да, после сверки документации API: адрес, credentials, названия частей, допустимые файлы и контракт ответа будут другими. Наша проверка Check Receipt предназначена только для учебного получателя.

Дальше по теме

Похожие материалы