NodeJS,Axios-将文件从本地服务器发布到另一台服务器

Tri*_*yen 4 multipartform-data node.js axios

我有一个API端点,可让客户端将其csv发布到我们的服务器,然后将其发布到其他服务器。我已经完成了服务器部分,将上传的文件保存到我们的服务器中,但是我无法完成另一部分。我不断收到错误消息{ message: 'File not found', code: 400 },这可能意味着文件永远无法到达服务器。我使用axios作为代理,有人知道如何完成此任务吗?谢谢。

// file = uploaded file
const form_data = new FormData();
form_data.append("file", fs.createReadStream(file.path));
const request_config = {
    method: "post",
    url: url,
    headers: {
        "Authorization": "Bearer " + access_token,
        "Content-Type": "multipart/form-data"
    },
    data: form_data
};
return axios(request_config);
Run Code Online (Sandbox Code Playgroud)

更新资料

正如axios doc指出的那样,我尝试调用的API需要一个文件

// data是要作为请求主体发送的数据// //仅适用于请求方法'PUT','POST'和'PATCH'// // transformRequest设置为no时,必须为以下类型之一://-字符串,普通对象,ArrayBuffer,ArrayBufferView,URLSearchParams //-仅浏览器:FormData,File,Blob //-仅节点:Stream,Buffer

有什么方法可以使axios整体发送文件?谢谢。

ble*_*lex 34

2个最旧的答案对我不起作用。然而,这成功了:

const FormData = require('form-data'); // npm install --save form-data

const form = new FormData();
form.append('file', fs.createReadStream(file.path));

const request_config = {
  headers: {
    'Authorization': `Bearer ${access_token}`,
    ...form.getHeaders()
  }
};

return axios.post(url, form, request_config);
Run Code Online (Sandbox Code Playgroud)

form.getHeaders()返回具有内容类型和边界的对象。
例如:

{ "content-type": "multipart/form-data; boundary=-------------------0123456789" }
Run Code Online (Sandbox Code Playgroud)

  • 这非常有帮助。多谢!这是另一个有用的示例,展示了如何在不使用文件系统的情况下模拟文件上传:https://github.com/axios/axios/issues/1006#issuecomment-320165427。 (2认同)

jam*_*non 11

我认为 createReadStream 是您的问题,因为它是异步的。尝试这个。由于 createReadStream 扩展了事件发射器,我们可以“监听”它何时完成/结束。

var newFile = fs.createReadStream(file.path);

// personally I'd function out the inner body here and just call 
// to the function and pass in the newFile
newFile.on('end', function() {
  const form_data = new FormData();
  form_data.append("file", newFile, "filename.ext");
  const request_config = {
    method: "post",
    url: url,
    headers: {
        "Authorization": "Bearer " + access_token,
        "Content-Type": "multipart/form-data"
    },
    data: form_data
  };
  return axios(request_config);
});
Run Code Online (Sandbox Code Playgroud)

  • 嗨詹姆斯。你的解决方案确实有效。但是,`createReadStream`是否将整个文件读取到内存中,如果是,我可能会遇到大文件的内存问题。 (2认同)
  • 因此,使用 Request 模块(导入它),您可以轻松地做到这一点: newFile.pipe(request(request_config)) 。我认为 axios 也可以做到。但想法是,在文件中流式传输,并将其通过管道传输到 request/axios 进行传输。 (2认同)
  • 你好!感谢你的回答!在打字稿中,我收到错误:“‘ReadStream’类型的参数不可分配给‘字符串’类型的参数| 布洛布。类型“ReadStream”缺少类型“Blob”的以下属性:大小、类型、arrayBuffer、切片和另外 2 个属性。有什么想法吗? (2认同)

小智 8

就我而言, fs.createReadStream(file.path) 不起作用。
我不得不使用缓冲区代替。

const form = new FormData();
form.append('file', fs.readFileSync(filePath), fileName);

const config = {
  headers: {
    Authorization: `Bearer ${auth.access_token}`,
    ...form.getHeaders(),
  },
};

axios.post(api, form.getBuffer(), config);

Run Code Online (Sandbox Code Playgroud)


Ale*_*var 5

这是您真正需要的:

const form_data = new FormData();
form_data.append("file", fs.createReadStream(file.path));

const request_config = {
  headers: {
    "Authorization": "Bearer " + access_token,
    "Content-Type": "multipart/form-data"
  },
  data: form_data
};

return axios
  .post(url, form_data, request_config);
Run Code Online (Sandbox Code Playgroud)