使用请求/请求从浏览器发布文件

时间:2018-02-14 16:27:22

标签: javascript node.js

我有一个Node.JS项目,服务器端和客户端由webpack提供支持。我希望将我的项目从axios / request组合转换为仅使用request,但我在浏览器上进行文件上传时遇到问题。我正在使用request-promise库,但无论我使用的是request还是request-promise,我都会遇到同样的问题。我的尝试是这样做:

return request.post({
  uri: `${BASE_URL}/files`,
  formData: {
    token: token,
    file: {value: filedata, options: {filename: filename}}
  }
})

其中filedata是使用File标记在用户计算机上查找文件而返回的input对象。我得到的错误是:

TypeError: self._form.on is not a function

这似乎是因为formData需要来自fs之类的可读流。如何获得request的正确输入?

2 个答案:

答案 0 :(得分:1)

在帖子请求中添加标题,这将有助于在您查找时使用流发送文件。

return request.post({
  uri: `${BASE_URL}/files`,
  formData: {
    token: token,
    file: {value: filedata, options: {filename: filename}}
  },
  headers: {'enctype': 'multipart/form-data'}
})

答案 1 :(得分:0)

我发现这需要一个非平凡的解决方案才能最终发挥作用。我使用FileReader将我从表单收到的File对象转换为ArrayBuffer。我手动将标题设置为' multipart / form-data'并使用multipart属性设置我的所有内容。最后,我需要将它全部包含在Promise中,因此我必须设置对象并适当地调用解析。

return new Promise((resolve) => {
  const fr = new FileReader()
  fr.onload = (event) => {
    return request({
      uri: `${BASE_URL}/files`,
      method: 'POST',
      headers: {
        'content-type': 'multipart/form-data'
      },
      multipart: {
        chunked: false,
        data: [
          {
            'Content-Disposition': 'form-data; name="token"',
            body: token
          },
          {
            'Content-Disposition': `form-data; name="file"; `filename="${filename}"`}`,
            body: event.target.result
          }
        ]
      }
    }).then(resolve)
  }
  fr.readAsArrayBuffer(filedata)
})