【发布时间】:2020-12-23 20:38:42
【问题描述】:
这很简单。使用此代码,任何上传的图像文件都已损坏且无法打开。 PDF 看起来不错,但我注意到它正在将值注入基于文本的文件中。这是 s3 中正确的文件大小,而不是像出了问题那样为零。我不确定这是否是 Express、SDK 或两者兼而有之的问题?是邮递员吗?我在今年 3 月的一个工作项目中构建了类似的东西,它运行得完美无缺。我无法再访问该代码进行比较。
没有错误,没有任何问题的迹象。
const aws = require("aws-sdk");
const stream = require("stream");
const express = require("express");
const router = express.Router();
const AWS_ACCESS_KEY_ID = "XXXXXXXXXXXXXXXXXXXX";
const AWS_SECRET_ACCESS_KEY = "superSecretAccessKey";
const BUCKET_NAME = "my-bucket";
const BUCKET_REGION = "us-east-1";
const s3 = new aws.S3({
region: BUCKET_REGION,
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY
});
const uploadStream = key => {
let streamPass = new stream.PassThrough();
let params = {
Bucket: BUCKET_NAME,
Key: key,
Body: streamPass
};
let streamPromise = s3.upload(params, (err, data) => {
if (err) {
console.error("ERROR: uploadStream:", err);
} else {
console.log("INFO: uploadStream:", data);
}
}).promise();
return {
streamPass: streamPass,
streamPromise: streamPromise
};
};
router.post("/upload", async (req, res) => {
try {
let key = req.query.file_name;
let { streamPass, streamPromise } = uploadStream(key);
req.pipe(streamPass);
await streamPromise;
res.status(200).send({ result: "Success!" });
} catch (e) {
res.status(500).send({ result: "Fail!" });
}
});
module.exports = router;
这是我的 package.json:
{
"name": "expresss3streampass",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"aws-sdk": "^2.812.0",
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"morgan": "~1.9.1"
}
}
更新:
经过进一步测试,我注意到 Postman 正在更改纯文本文件。比如这个源文件:
{
"question_id": null,
"position_type_id": 1,
"question_category_id": 1,
"position_level_id": 1,
"question": "Do you test your code before calling it \"done\"?",
"answer": "Candidate should respond that they at least happy path test every feature and bug fix they write.",
"active": 1
}
...落入桶中后的样子:
----------------------------472518836063077482836177
Content-Disposition: form-data; name="file"; filename="question.json"
Content-Type: application/json
{
"question_id": null,
"position_type_id": 1,
"question_category_id": 1,
"position_level_id": 1,
"question": "Do you test your code before calling it \"done\"?",
"answer": "Candidate should respond that they at least happy path test every feature and bug fix they write.",
"active": 1
}
----------------------------472518836063077482836177--
我不得不认为这是问题所在。邮递员是这个等式中唯一改变的东西,从这段代码第一次为我工作起。我的请求标头如下所示:
我是最初添加“application/x-www-form-urlencoded”标头的人。如果我现在使用它,我最终会在存储桶中得到一个 0 字节的文件。
【问题讨论】:
-
您是否有不想使用 multer 的特定原因?
-
@relief.melone 是的 - 这是流式传输文件,而不是用可能太大的文件炸毁容器,或者在大型上传时锁定线程。
-
你也可以使用带有 multer 的流,而不是先将其上传到容器中。我不确定,但我非常有信心 multer-s3-storage 可以做到这一点,而且我在为 multer gitlab.com/relief-melone/multer-s3-sharp-resizer 编写的存储引擎中也是如此。但是,我仍然不确定是什么导致了您的代码出现问题,因为我的方法与您的方法几乎相同(而且我也在使用 Postman 进行测试)。一旦有时间,我仍然会仔细研究一下。我知道您不仅想让它发挥作用,而且还想知道出了什么问题。
-
是您的服务器的目标只是从用户那里挑选一个文件并将其放在 S3 上?
标签: javascript node.js express amazon-s3 aws-sdk