Повторная загрузка файла после его передачи в AWS lambdas(nodejs) + API gateway

У меня есть REST API, созданный с использованием AWS Lambdas и шлюза API.

Этот API поддерживает загрузку файлов, и у меня есть требование анализировать загруженные файлы, а затем отправлять эти файлы по отдельности в другой источник в виде данных формы.

Когда я отправляю два изображения через почтальона и регистрирую тело события, я получаю следующую строку. (У него два файла)

----------------------------269453880547064499146449
Content-Disposition: form-data; name = "file"; filename = "smiling.png"
Content-Type: image/png

�PNG


IHDR��asBIT|d�^IDAT8���=KBa��IB����"�-P\�6!Bz�D�c�hk�K�hAV`Km���K�PKm��Oý�R�-�O��<�#ZkzT���4B��nMȑ0����@#�A�- ����7w��"�fY��J�C�)�Z`D3�a��E�h���<F�7w����d�ɉ7���Y�?f�+Y�&9�B����P����`%�d:�T
�m�h�K�`����zT;�e �mc�$=A�q���&@Y��4O=W����P@�T���*��V�t`a��H�UD��6��Һ���W[��,  ��u�Ea�.c�-��S�z���Q�`���S�~y��xݡ�O�]IEND�B`�
----------------------------269453880547064499146449
Content-Disposition: form-data; name = "file"; filename = "smiling.png"
Content-Type: image/png

�PNG


IHDR��asBIT|d�^IDAT8���=KBa��IB����"�-P\�6!Bz�D�c�hk�K�hAV`Km���K�PKm��Oý�R�-�O��<�#ZkzT���4B��nMȑ0����@#�A�- ����7w��"�fY��J�C�)�Z`D3�a��E�h���<F�7w����d�ɉ7���Y�?f�+Y�&9�B����P����`%�d:�T
�m�h�K�`����zT;�e �mc�$=A�q���&@Y��4O=W����P@�T���*��V�t`a��H�UD��6��Һ���W[��,  ��u�Ea�.c�-��S�z���Q�`���S�~y��xݡ�O�]IEND�B`�
----------------------------269453880547064499146449--


Я использовал lambda-multipart-parser для разбора этого тела и извлечения метаданных.

import parser from 'lambda-multipart-parser'

....

const result = await parser.parse(event)

Результат выше дает файлы со следующим типом.

   {
        filename: string
        content: Buffer
        contentType: string
        encoding: string
        fieldname: string
    }

У меня проблема в том, что я должен отправлять эти файлы по отдельности на другой сервер как multipart/formdata.

Подходы, которые я пробовал до сих пор.

Подход 1

Использовал регулярное выражение для разделения тела события по границе, границей сети в примере является ----------------------------269453880547064499146449.

 const splitFileBody = event.body?.split(fileBoundary)

После разделения у меня осталась строка.

// In this example I am only trying to send one file

formData.append('file', splitFileBody[0])

Результат: описанный выше подход дает мне код состояния 400 HTTP вместе со следующей ошибкой.

тело вашего POST-запроса неправильно сформировано multipart/form-data

Подход 2

Попытался создать объект типа File в лямбда-выражении, используя проанализированный файл следующим образом.

    const fileC = new File([file.content], file.fieldname, { type: file.contentType, lastModified: Number(new Date()) })
    console.info('fileC', fileC)
    const formData = new FormData()
    formData.append('file', fileC)

Результат: журналы Lambda выдают ошибку File is not defined.

Подход 3

Передал проанализированную информацию в form.append напрямую без new File

form.append('file', file.content, {
    filename: file.filename,
    contentType: file.contentType
  });

Результат: описанный выше подход дает мне код состояния HTTP 400 вместе со следующей ошибкой.

тело вашего POST-запроса неправильно сформировано multipart/form-data

Верны ли мои подходы. Если нет, что мне делать по-другому. Если подходы выше подходят, то какой из них лучше и как избежать ошибок?

Дополнительная информация

  • Я использую пакет form-data, потому что я продолжал получать FormData is not defined during the lambda runtime.
import FormData from 'form-data'

....

formData.append('file', file.content, {
      filename: file.filename
    })

  • Я использую axios, чтобы сделать почтовый запрос
  const res = await axios.post(URL, formData, {
      headers: {
        ...formData.getHeaders(),
        'content-length': file.content.length
      }
    })
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги &lt;ul&gt; и &lt;li&gt; для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
2
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Содержимое проанализированного файла может быть напрямую добавлено к formData из form-data следующим образом.

const result = await parser.parse(event)

const formData = new FormData();


for (const file of result.files) {

  formData.append('file', file.content, {
    filename: file.filename,
    contentType: file.contentType
  });
}

Кроме того, content-length должно иметь значение formData.getLengthSync() следующим образом. Причина в том, что formData может содержать другие добавленные к нему поля, а file.content.length содержит только размер файла, а не другие добавленные данные.

await axios.post(URL, formData, {
  headers: {
    ...formData.getHeaders(),
    'Content-Length': formData.getLengthSync()
  }
})

Спасибо за комментарий @traynor. Это дает мне The body of your POST request is not well-formed multipart/form-data. похожее на первый подход. Я обновлю свой вопрос, чтобы включить этот подход.

Muljayan 16.02.2023 04:26

Можете ли вы включить код, где вы делаете запрос, т.е. проходите formData

traynor 16.02.2023 07:58

Привет, я обновил дополнительную информацию внизу

Muljayan 16.02.2023 08:30

Попробуйте обновленный код, попробуйте сделать запрос без заголовков и т. д.

traynor 16.02.2023 08:47

Привет, Трейнор, я отредактировал твой ответ, добавив улучшения и рабочее решение.

Muljayan 18.02.2023 14:34

Большой. Я думал, что это была часть запроса, вы были на правильном пути, потому что, если бы простой запрос не работал, моей следующей попыткой было бы поиграть с headers, согласно документам: npmjs.com/package/form-data #аксиос

traynor 18.02.2023 14:59

Другие вопросы по теме