如何通过axios将本地图片文件发送到部署了express-fileupload的服务器

Crystal
  • 3
新手上路,请多包涵

需求

用户通过微信向机器人发送图片,然后机器人会将图片接收并保存至server A(受限于框架本身,必须先保存图片至本地)。然后,server A通过axiosserver B发起post请求,B通过express-fileupload获取到文件并保存。

代码

发送图片的server A

// 目前在本机调试,启动了两个nodejs
const imgHosting = `http://127.0.0.1:1255/upload`;

async function test() {
  try {
    const formData = new FormData();
    const filePath = path.join(__dirname, "./22.jpg"); //要发送的图片
    const fileName = 'test.jpg';

    formData.append("img", fs.createReadStream(filePath), fileName);

    const result = (
      await axios.post(
        // url
        imgHosting,
        // 参数列表
        formData,
        // 请求头配置
        { header: { "Content-Type": "multipart/form-data" } }
      )
    ).data;
    console.log(result);
  } catch (err) {
    console.log(err);
  }
}

test();



接收方server B

app.post('/upload', (req, res) => {
    try {
        console.log(req.files);
        if (!req.files) {
            console.log('test');
            const data = {
                code: 404,
                status: "No file uploaded",
                link: "undefined"
            };
            res.json(data);
        } else {
            console.log('uploading...');
            let img = req.files.img; // 声明字段名为 img 的图片数据为 img 变量
            let md5 = crypto.createHash('md5').update(img.name).digest('hex'); 
            let ext = path.extname(img.name);
            const cryptedName = `${md5}${ext}`;
            const uploadPath = path.join(__dirname, '../uploads', cryptedName);
            img.mv(uploadPath); 
            const data = {
                code: 200,
                status: "upload ok",
                link: "http://127.0.0.1:1255/pic/" + md5 + ext
            };
            res.json(data);
        }
    } catch (err) {
        res.status(500).send(err);
    }
});

问题

无论我通过readFile还是createReadStream读取文件,发送至server B时都获得了No file uploaded的反馈。我猜测也许是因为我发送过去的文件是stream || buffer,因此接收方无法识别。可在我的案例中,无法通过前端页面的<input>去指定file类型,我该如何修改才能让axios将图片文件从一个后端发送至另一个后端呢?

回复
阅读 657
2 个回答
✓ 已被采纳

对你的问题来说,文件上传就是指的通过客户端上传文件的行为,server之间是不存在文件上传这件事情的。例如serverA把用户上传的文件存入了数据库,难道数据复制的时候也要先把文件从数据库取出、另存、流读取再发送吗?
req.files这个就是专门用来保存客户端上传文件的,对你来说并不需要这个。你的行为对于服务器之间的通信来说就是A把内容发送给B,B收到之后做个处理(比如存库或存文件)。

我猜测也许是因为我发送过去的文件是stream || buffer,因此接收方无法识别。

应该不是这个问题,接收方是 express-fileupload ,客户端指定了Content-Type,服务器会对应处理,现在怀疑的点是:

1:你的 express-fileupload 有引用吗?或者引用正确吗?因为req之所有files属性,就是这个中间件做的

2:

{ header: { "Content-Type": "multipart/form-data" } }

这里是否有指定成功,可以在服务端打印下这个header看下是什么值,或者可以试试用
{ header: ...formData.getHeaders() }

formData本身有设置 header的API

3:如何这两个都没有问题,写一个html的表单页面测试一下你的服务端接受方是不是正确的,先验证下服务端接受方。

宣传栏