NodeJS、Axios - post 文件从本地服务器到另一台服务器

NodeJS, Axios - post file from local server to another server

我有一个 API 端点,可以让客户端 post 他们的 csv 到我们的服务器,然后 post 它到其他服务器。我已经完成了将上传文件保存到我们服务器的服务器部分,但我无法完成另一部分。我不断收到错误 { 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);

更新

如下 axios 文档所述,我尝试调用的 API 需要一个文件

// data is the data to be sent as the request body // Only applicable for request methods 'PUT', 'POST', and 'PATCH' // When no transformRequest is set, must be of one of the following types: // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams // - Browser only: FormData, File, Blob // - Node only: Stream, Buffer

有没有什么办法可以让axios把一个文件作为一个整体来发送?谢谢。

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

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);
});

这才是你真正需要的:

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);

最旧的 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);

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

{ "content-type": "multipart/form-data; boundary=-------------------0123456789" }

在我的例子中,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);

我制作了一个拦截器,您可以连接到 axios 以在节点中处理这种情况:axios-form-data。欢迎任何反馈。

  • npm i axios-form-data
  • 示例:
import axiosFormData from 'axios-form-data';
import axios from 'axios';

// connect axiosFormData interceptor to axios
axios.interceptors.request.use(axiosFormData);

// send request with a file in it, it automatically becomes form-data
const response = await axios.request({
  method: 'POST',
  url: 'http://httpbin.org/post',
  data: {
    nonfile: 'Non-file value',
    // if there is at least one streamable value, the interceptor wraps the data into FormData
    file: createReadStream('somefile'),
  },
});

// response should show "files" with file content, "form" with other values
// and multipart/form-data with random boundary as request header
console.log(response.data);