问题描述
我有一个非常简单的设置,使用:Axios > Express > S3 (v3:@aws-sdk/client-s3
)。
当文件到达 Node 端时,它会自动转换为 Node File Object
格式(我不知道如何处理)。 @aws-sdk
尝试将其转换为缓冲区,这会引发 buffer.js:333
中的错误。
TypeError [ERR_INVALID_ARG_TYPE]:第一个 参数必须是字符串类型或 Buffer、ArrayBuffer、 或数组或类似数组的对象。收到一个文件实例
这是脚本的相关部分。
// Frontend.js
const sendImage = () => {
const image = document.querySelector('#photoupload');
const formData = new FormData();
formData.append('image',image.files[0]);
axios.post('http://192.168.1.152:3200/addImage',formData,{
headers: {
'content-type': 'multipart/form-data',},});
};
// express-server.js
app.use(cors());
app.use(formidable())
app.post('/addImage',(req,res) => {
const file = req.files;
uploadOnetoBucket('my_s3_bucket',file);
});
// s3_uploadMethod.js
const uploadOnetoBucket = (bucketName,file) => {
const params = {
Bucket: bucketName,ACL: 'public-read',Body: file.image,Key: file.image.name,};
const s3Upload = s3.send(new PutObjectCommand(params));
// handle Promises
};
我不太确定如何解决这个问题。一个问题,我应该如何处理节点文件对象,以便 S3 PutObjectCommand
可以使用它?
另一个问题是,文件上传的最佳实践是什么,我见过人们谈论转换为 base64 缓冲区,而其他人则说要流式传输。
感谢你们的帮助!
解决方法
一种解决方案是将前端的文件转换为 base64
,将其放入 FormData
对象中,然后在服务器端将其转换回。这种方法的缺点是 base64
字符串比原始文件大 30% 左右。我认为那里有更好的解决方案。
修改后的代码使用了内置的 FileReader Object
// Frontend.js
const sendImage = () => {
const image = document.querySelector('#photoupload').files[0];
const reader = new FileReader();
const formData = new FormData();
reader.addEventListener('loadend',() => {
formData.append('image',image.name + reader.result);
axios.post('http://192.168.1.152:3200/addImage',formData,{
headers: {
'content-type': 'multipart/form-data',},});
});
reader.readAsDataURL(image);
};
// server.js
app.use(cors());
app.use(formidable());
app.post('/addImage',(req,res) => {
const file = req.fields;
uploadOneToBucket('my_s3_bucket',file.image);
});
// s3_uploadMethod.js
const uploadOneToBucket = (bucketName,file) => {
const data = file.split(',');
const decodedBuffer = Buffer.from(data[1],'base64');
const filename = (data[0].split('data')[0]);
const params = {
Bucket: bucketName,ACL: 'public-read',Body: decodedBuffer,Key: filename,};
// ...