gpt4 book ai didi

express - 为什么在多部分上传到在 aws lambda 中运行的 express 过程中文件被损坏?

转载 作者:行者123 更新时间:2023-12-03 13:35:56 25 4
gpt4 key购买 nike

拥有一个带有 redux 客户端和 express webapi 的 SPA。用例之一是将单个文件从浏览器上传到快速服务器。 Express 正在使用 multer中间件对上传的文件进行解码并将其放入 req 上的数组中目的。在 localhost 上运行时,一切都按预期工作。

但是,当应用程序部署到 AWS 时,它无法按预期运行。部署将 express api 推送到 AWS Lambda 函数,redux 客户端静态 Assets 由 Cloudfront CDN 提供服务。在那种环境中,上传的文件确实会到达 express 服务器,由 multer 处理,并且文件最终会成为 req.files 中的第一个(也是唯一一个)项目。预期的数组。

问题是文件包含错误的字节。例如,当我上传一个长度为 2795 字节的示例图像时,最终被 multer 解码的文件长度为 4903 字节。在 multer 解码并将它们放入 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)
}

我尝试使用 MemoryStorage 和 DiskStorage 设置 multer。两者都可以在 localhost 和 aws lambda 上工作,但是两者都表现出相同的行为——文件更大并且在存储中已损坏。

我还尝试将 multer 设置为全局中间件(通过 app.use )和上传路由上的特定于路由的中间件(通过 routes.post('the url', multerMiddlware, controller.uploadAction) 。同样,两者都表现出相同的行为。Multer 中间件的配置如下:
const multerMiddleware = multer({/* optionally set dest: '/tmp' */})
.array('files')

一个区别是,在 localhost 上,客户端和 express 都通过 http 提供服务,而在 aws 中,客户端和 express 都通过 https 提供服务。我不相信这会有所作为,但我还无法测试——要么通过 https 运行 localhost,要么通过 http 在 aws 中运行。

我注意到的另一件奇怪的事情是,当 multer 中间件存在时,其他中间件似乎无法按预期运行。而不是 next()函数向下移动到 Controller Action ,相反,其他中间件将在 Controller Action 调用之前完全退出,并且当 Controller 调用退出时,控制在 next() 之后不会流回中间件称呼。删除 multer 中间件后,其他中间件会按预期运行。然而,这个观察是在 localhost 上进行的,整个端到端用例确实按预期运行。

当部署到云而不是本地主机时,什么可能会弄乱上传的图像文件有效负载?难道真的是https有所作为吗?

更新 1

当我上传 this file (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 个字节。

更新 3

尝试使用更大的文本文件(12132 字节长)上传,结果与更新 2 中的结果相同——文件保持不变,没有损坏。

最佳答案

可能的答案:

找到这个 https://forums.aws.amazon.com/thread.jspa?threadID=252327

API Gateway does not natively support multipart form data. It is possible to configure binary passthrough to then handle this multipart data in your integration (your backend integration or Lambda function).



如果您在 AWS 中使用 API Gateway 事件来触发托管您的快速服务器的 lambda,您似乎需要另一种方法。

或者,您可以根据 https://stackoverflow.com/a/41770688/304832 配置 API 网关以使用二进制有效负载。

或者,直接从您的客户端上传到签名的 s3 url(或公共(public) URL)并使用它来触发另一个 lambda 事件。

在我们有机会尝试不同的 API 网关设置之前,我们找到了一个临时解决方法:使用 FileReader将文件转换为 base64 文本字符串,然后提交。只要有效负载是文本,上传似乎没有任何问题。

关于express - 为什么在多部分上传到在 aws lambda 中运行的 express 过程中文件被损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50989630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com