【问题标题】:Node JS upload file streams over HTTPNode JS 通过 HTTP 上传文件流
【发布时间】:2016-10-27 01:21:14
【问题描述】:

我正在将我的一个项目从 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.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 标头,否则端点确实会给我一个适当的错误。否则,我不确定这 2 个包是如何使用流构建主体的,但正如我所说,fetchaxios 也会产生与 got 完全相同的错误。

如果您想要任何使用fetchaxios 的sn-ps,我也很乐意发布它们。

【问题讨论】:

  • 不确定这是否有帮助,但根据获取的文档,您需要将 FormData 作为对象的主体传递 - github.com/sindresorhus/got#form-data
  • 我也试过这个。使用form-data 包,我用“内容”和流信息调用append,但我仍然遇到同样的问题。我将编辑我的问题以反映这一点。

标签: node.js request fetch axios


【解决方案1】:

我知道这个问题是不久前被问到的,但我也错过了简单的pipe support from the request package

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”,但我希望以下 2 个示例可以帮助有兴趣使用 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);
})();

【讨论】:

  • 感谢 Axios 解决方案。响应类型“流”在用作多部分 POST 时工作正常
  • 感谢您的“HTTP/HTTPS 支持管道!”示例 - 该实现与我的 request 实现最接近。自从request 被贬值后,它就一直在尝试摆脱它。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    对我来说,当我在 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 中名为“文件”的文件

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 2010-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多