Node JS通过HTTP上传文件流



我正在将我的一个项目从request切换到一些更轻量级的项目(例如got, axios或fetch)。一切都很顺利,然而,我有一个问题,当试图上传一个文件流(PUTPOST)。它可以很好地处理请求包,但其他三个都从服务器返回一个500。

我知道500通常意味着服务器端的问题,但它只与我正在测试的HTTP包一致。当我将代码还原为使用request时,它工作得很好。

这是我当前的请求代码:

Request.put(`http://endpoint.com`, {
  headers: {
    Authorization: `Bearer ${account.token.access_token}`
  },
  formData: {
    content: fs.createReadStream(localPath)
  }
}, (err, response, body) => {
  if (err) {
    return callback(err);
  }
  return callback(null, body);
});

下面是使用另一个包(在本例中为got)的一个尝试:

got.put(`http://endpoint.com`, {
  headers: {
    'Content-Type': 'multipart/form-data',
    Authorization: `Bearer ${account.token.access_token}`,
  },
  body: {
    content: fs.createReadStream(localPath)
  }
})
  .then(response => {
    return callback(null, response.body);
  })
  .catch(err => {
    return callback(err);
  });

根据得到的文档,我也尝试使用form-data包与它结合根据它的例子,我仍然得到同样的问题。

我可以收集的这2之间的唯一区别是got,我必须手动指定Content-Type头,否则端点确实给了我一个适当的错误。否则,我不确定这两个包是如何用流构造主体的,但正如我所说,fetchaxios也会产生与got完全相同的错误。

如果你想使用fetchaxios的任何片段,我也很乐意发布它们。

我知道刚才有人问过这个问题,但是我也错过了请求包

中的简单管道支持
const request = require('request');
request
  .get("https://res.cloudinary.com/demo/image/upload/sample.jpg")
  .pipe(request.post("http://127.0.0.1:8000/api/upload/stream"))

// Or any readable stream
fs.createReadStream('/Users/file/path/localFile.jpeg')
  .pipe(request.post("http://127.0.0.1:8000/api/upload/stream"))

,不得不做一些实验,从现有的库中找到类似的特性。

不幸的是,我没有使用过"got"但我希望下面的两个例子可以帮助那些对使用Native http/https库或流行的axios库感兴趣的人


HTTP/HTTPS

支持管道!

const http = require('http');
const https = require('https');
console.log("[i] Test pass-through: http/https");
// Note: http/https must match URL protocol
https.get(
  "https://res.cloudinary.com/demo/image/upload/sample.jpg",
  (imageStream) => {
    console.log("    [i] Received stream");
    imageStream.pipe(
      http.request("http://localhost:8000/api/upload/stream/", {
        method: "POST",
        headers: {
          "Content-Type": imageStream.headers["content-type"],
        },
      })
    );
  }
);
// Or any readable stream
fs.createReadStream('/Users/file/path/localFile.jpeg')
  .pipe(
    http.request("http://localhost:8000/api/upload/stream/", {
      method: "POST",
      headers: {
        "Content-Type": imageStream.headers["content-type"],
      },
    })
  )

Axios

注意imageStream.data的用法,并且它在Axios配置中被附加到data

const axios = require('axios');
(async function selfInvokingFunction() {
  console.log("[i] Test pass-through: axios");
  const imageStream = await axios.get(
    "https://res.cloudinary.com/demo/image/upload/sample.jpg",
    {
      responseType: "stream", // Important to ensure axios provides stream
    }
  );
  console.log("  [i] Received stream");
  const upload = await axios({
    method: "post",
    url: "http://127.0.0.1:8000/api/upload/stream/",
    data: imageStream.data,
    headers: {
      "Content-Type": imageStream.headers["content-type"],
    },
  });
  console.log("Upload response", upload.data);
})();

看起来这是一个标题问题。如果我使用标题直接从FormData(即,headers: form.getHeaders()),只是在我的附加标题之后(Authorization),然后这最终工作得很好。

当我在FormData上添加其他参数时,

const form = new FormData();
form.append('file', fileStream);

const form = new FormData();
form.append('file', fileStream, 'my-whatever-file-name.mp4');

这样我就可以将流从我的后端发送到另一个后端,在节点中等待multipart/form-data中名为file的文件

相关内容

  • 没有找到相关文章

最新更新