Нет, я должен был это отложить и перешел на что-то еще. Запись моих результатов здесь, чтобы поделиться с командой на случай, если это будет передано кому-то еще. На данный момент вопрос все еще не решен / без ответа
СПА с редукционным клиентом и экспресс вебапи. Одним из вариантов использования является загрузка одного файла из браузера на экспресс-сервер. Экспресс используетmulter
промежуточное программное обеспечение для декодирования загружаемого файла и размещения его в массивеreq
объект. Все работает, как ожидалось, при запуске на localhost.
Однако когда приложение развернуто в AWS, оно не работает должным образом. Развертывание передает Express API в функцию AWS Lambda, а статические ресурсы клиента-редуктора обслуживаются Cloudfront CDN. В этой среде загруженный файл попадает на экспресс-сервер, обрабатывается multer, и файл в конечном итоге становится первым (и единственным) элементом вreq.files
массив, где он должен быть.
Проблема в том, что файл содержит неправильные байты. Например, когда я загружаю образец изображения, длина которого составляет 2795 байт, длина файла, декодируемого мультером, составляет 4903 байта. Другие изображения, которые я пробовал, всегда заканчивали тем, что увеличивались примерно на один и тот же коэффициент к тому времени, когда мультитер декодировал и помещал их в массив req.files. В результате файлы повреждены и не отображаются в виде изображений.
Файл загружается так:
<input type="file" name="files" onChange={this.onUploadFileSelected} />
...
onUploadFileSelected = (e) => {
const file = e.target.files[0]
var formData = new FormData()
formData.append("files", file)
axios.post('to the url', formData, { withCredentials: true })
.then(handleSuccessResponse).catch(handleFailResponse)
}
Я попытался настроить multer как с помощью MemoryStorage, так и DiskStorage. Обе они работают как на локальном хосте, так и в лямбда-aws, однако оба демонстрируют одинаковое поведение - файл имеет больший размер и поврежден в хранилище.
Я также попытался настроить multer как глобальное промежуточное ПО (черезapp.use
) и в качестве промежуточного программного обеспечения для маршрута на маршруте загрузки (черезroutes.post('the url', multerMiddlware, controller.uploadAction)
, Опять же, оба демонстрируют одинаковое поведение. Промежуточное программное обеспечение Multer настроено так:
const multerMiddleware = multer({/* optionally set dest: '/tmp' */})
.array('files')
Одно из отличий состоит в том, что на локальном хосте и клиент, и экспресс обслуживаются через http, тогда как в aws и клиент, и экспресс обслуживаются через https. Я не верю, что это имеет значение, но я пока не смог протестировать - либо запуск localhost через https, либо запуск aws через http.
Еще одна странная вещь, которую я заметил, заключалась в том, что при наличии промежуточного программного обеспечения для нескольких устройств другие промежуточные программы, похоже, не работают должным образом. Скорее чемnext()
Функция перемещает поток вниз к действию контроллера, вместо этого другие промежуточные программы полностью выходят до вызова действия контроллера, а при выходе из вызова контроллера управление не возвращается обратно в промежуточное программное обеспечение послеnext()
вызов. Когда промежуточное программное обеспечение удалено, другие промежуточные программы функционируют должным образом. Однако это наблюдение относится к локальному узлу, где весь сценарий сквозного использования функционирует должным образом.
Что может испортить полезную нагрузку загруженного файла изображения при развертывании в облаке, но не на локальном хосте? Может ли быть действительно https, что имеет значение?
Обновление 1Когда я загружаюэтот файл (11228 байт)
Вот HAR Chrome дает мне для локальной (ожидаемой) загрузки файла:
"postData": {
"mimeType": "multipart/form-data; boundary=----WebKitFormBoundaryC4EJZBZQum3qcnTL",
"text": "------WebKitFormBoundaryC4EJZBZQum3qcnTL\r\nContent-Disposition: form-data; name=\"files\"; filename=\"danludwig.png\"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundaryC4EJZBZQum3qcnTL--\r\n"
}
Вот что HAR Chrome дает мне для загрузки файла aws (поврежден):
"postData": {
"mimeType": "multipart/form-data; boundary=----WebKitFormBoundaryoTlutFBxvC57UR10",
"text": "------WebKitFormBoundaryoTlutFBxvC57UR10\r\nContent-Disposition: form-data; name=\"files\"; filename=\"danludwig.png\"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundaryoTlutFBxvC57UR10--\r\n"
}
Сохраненный поврежденный файл изображения имеет длину 19369 байт.
Обновление 2Я создал текстовый файл с текстомhello world
это 11 байтов длиной и загрузил его. Это не повреждается в AWS. Это имеет место, даже если я загружаю его с суффиксом txt или png, при сохранении он заканчивается длиной 11 байт.
Попытка загрузки с использованием намного большего текстового файла (длиной 12132 байта) и имела тот же результат, что и в обновлении 2 - файл сохраняется без изменений, не поврежден.