我尝试从React发送img文件和其他文本信息到Express服务器,使用multer作为中间件将img保存在aws S3中,并将S3中的img url和其他信息保存在服务器DB中。
我一直得到MulterError:意外的字段错误,而我尝试上传。单个或上传。数组中的multer或更改内容类型等…我已经试了几个小时了,现在我甚至不知道如何修改它。
S3访问的方法是作为IAM用户使用。env中的access/secret access key。
my react side code
const Item = () => {
const {
register,
handleSubmit,
formState: { isSubmitting },
} = useForm({
defaultValues: {
itemName: "",
imgs: null,
webpImgs: null,
price: null,
category: "",
brand: "",
sale: null,
},
});
const onSubmit = async (data) => {
const formData = new FormData();
var sumFile = document.querySelector("#sumFile");
formData.append("sumFile", sumFile?.files[0]);
const blob = new Blob([data], {
type: "application/json",
});
formData.append("info", blob);
try {
addItem(formData).then(async (res) => {
if (res.status === 200) {
alert("test");
} else {
alert("fail");
}
});
} catch (err) {
return err;
}
};
return (
<form className="user-form" onSubmit={handleSubmit(onSubmit)}>
<select {...register("category")}>
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
</select>
<select {...register("type")}>
<option value="Short">Short</option>
<option value="Long">Long</option>
<option value="Dress">Dress</option>
</select>
<input {...register("itemName")} placeholder="itemName" />
<input
{...register("file")}
type="file"
name="sumFile"
id="sumFile"
accept="image/*"
/>
<input {...register("price")} placeholder="price" />
<input {...register("brand")} placeholder="brand" />
<input {...register("sale")} placeholder="sale" />
<button disabled={isSubmitting}>Add</button>
</form>
);
};
表达代码。我想传递img url到下一个函数,但不能尝试,因为我还没有保存img到S3。
const express = require("express");
const router = express.Router();
const item = require("../controllers/item");
const { S3Client} = require("@aws-sdk/client-s3");
const dotenv = require("dotenv");
const multer = require("multer");
const multerS3 = require("multer-s3");
const s3 = new S3Client();
dotenv.config();
const upload = multer({
storage: multerS3({
s3: s3,
bucket: "bucket name",
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
cb(null, Date.now().toString());
},
}),
});
router.post("/additem", upload.array("sumFile", 2), function (req, res, next) {
console.log(req.files);
res.status(200).send("Successfully uploaded ");
});
module.exports = router;
in network req payload
------WebKitFormBoundaryJxBVt4RCvqhg3w9L Content-Disposition: form-data;name ="sumFile";文件名="a.png"内容类型:图像/png
------WebKitFormBoundaryJxBVt4RCvqhg3w9L Content-Disposition: form-data;name ="info";文件名="blob"内容类型:application/json
错误细节
Unexpected field MulterError:意外字段@ wrappedFileFilter (/Users/home/self/backtest/server/node_modules/multer/index.js:40:19)多部分。(/用户/home/自/val/服务器/node_modules/乘/lib/make-middleware.js: 107:7)多部分。发出(节点:事件:513:28)在HeaderParser。cb(/用户/home/自/val/服务器/node_modules/餐馆工/lib/类型/multipart.js: 358:14)在HeaderParser。push(自我/用户/home//val/服务器/node_modules/餐馆工/lib/类型/multipart.js: 162:20)在SBMH。ssCb [as _cb] (/Users/home/self/backtest/server/node_modules/busboy/lib/types/multipart.js:394:37)at feed (/Users/home/self/backtest/server/node_modules/streamsearch/lib/sbmh.js:219:14)在SBMH。推动(/用户/home/自/val/服务器/node_modules/streamsearch/lib/sbmh.js: 104:16)多部分。_write(/用户/home/自/val/服务器/node_modules/餐馆工/lib/类型/multipart.js: 567:19)at writeOrBuffer (node:internal/streams/writable:392:12)
不要尝试上传两个blob,而是将表单数据分离到单独的字段中。
另外,由于您使用了register("file")
,因此该文件将已经在data
中。
const { file, ...fields } = data;
const formData = Object.entries(fields).reduce(
(fd, [key, val]) => (fd.append(key, val), fd),
new FormData()
);
formData.append("sumFile", file); // or you could save time and register "sumFile"
在服务器端,使用upload.single()
将文件提取到req.file
和req.body
中,用于剩余的数据
router.post("/additem", upload.single("sumFile"), (req, res, next) => {
console.log(req.file);
const { category, type, itemName, price, brand, sale } = req.body;
res.status(200).send("Successfully uploaded ");
});