使用本机nodejs中的获取将文件上传到REST API

发布于 2025-02-06 03:57:34 字数 3041 浏览 1 评论 0原文

我正在尝试使用nodej中的本机fetch()API将文件上传到REST API。 到目前为止,我已经成功地发布了其他获取请求,但是此文件上传给我带来了很多麻烦。

我具有以下功能 -

async function uploadDocumentToHub(hub_entity_id, document_path) {
  let formData = new FormData();
  formData.append("type", "Document");
  formData.append("name", "ap_test_document.pdf");
  formData.append("file", fs.createReadStream("ap_test_document.pdf"));
  formData.append("entity_object_id", hub_entity_id);

  const form_headers = {
    Authorization: auth_code,
    ...formData.getHeaders(),
  };

  console.log(
    `Uploading document ap_test_document.pdf to hub (${hub_entity_id}) `
  );
  console.log(formData);

  let raw_response = await fetch(urls.attachments, {
    method: "POST",
    headers: form_headers,
    body: formData,
  });
  
  console.log(raw_response);
}

然后使用以下代码运行 -

async function async_main() {
  ......
.......
  await uploadDocumentToHub(hub_entity_id, document_path);
}

// main();
async_main();

并且我不断遇到以下错误 -

node:internal/deps/undici/undici:5536
          p.reject(Object.assign(new TypeError("fetch failed"), { cause: response.error }));
                                 ^

TypeError: fetch failed
    at Object.processResponse (node:internal/deps/undici/undici:5536:34)
    at node:internal/deps/undici/undici:5858:42
    at node:internal/process/task_queues:140:7
    at AsyncResource.runInAsyncScope (node:async_hooks:202:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  cause: TypeError: object2 is not iterable
      at action (node:internal/deps/undici/undici:1660:39)
      at action.next (<anonymous>)
      at Object.pull (node:internal/deps/undici/undici:1708:52)
      at ensureIsPromise (node:internal/webstreams/util:172:19)
      at readableStreamDefaultControllerCallPullIfNeeded (node:internal/webstreams/readablestream:1884:5)
      at node:internal/webstreams/readablestream:1974:7
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
}

我对正在发生的事情和此错误感到困惑。有什么想法吗? 以下代码正确地上传了文件(从邮递员生成自动生成,为安全性删除了一些数据) - 对

var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('type', 'Document');
data.append('name', 'ap_test_document.pdf');
data.append('file', fs.createReadStream('kX3bdHb1G/ap_test_document.pdf'));
data.append('entity_object_id', '<id>');

var config = {
  method: 'post',
  url: '<url>',
  headers: { 
    'Authorization': '<token>', 
    ...data.getHeaders()
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

某些帮助将不胜感激。

谢谢!

I'm trying to use the native fetch() API in NodeJS to upload a file to a REST API.
So far, I've made other GET and POST requests successfully, but this file upload is causing me a lot of trouble.

I have the following function -

async function uploadDocumentToHub(hub_entity_id, document_path) {
  let formData = new FormData();
  formData.append("type", "Document");
  formData.append("name", "ap_test_document.pdf");
  formData.append("file", fs.createReadStream("ap_test_document.pdf"));
  formData.append("entity_object_id", hub_entity_id);

  const form_headers = {
    Authorization: auth_code,
    ...formData.getHeaders(),
  };

  console.log(
    `Uploading document ap_test_document.pdf to hub (${hub_entity_id}) `
  );
  console.log(formData);

  let raw_response = await fetch(urls.attachments, {
    method: "POST",
    headers: form_headers,
    body: formData,
  });
  
  console.log(raw_response);
}

which I then run with the following code -

async function async_main() {
  ......
.......
  await uploadDocumentToHub(hub_entity_id, document_path);
}

// main();
async_main();

And I keep getting the following error -

node:internal/deps/undici/undici:5536
          p.reject(Object.assign(new TypeError("fetch failed"), { cause: response.error }));
                                 ^

TypeError: fetch failed
    at Object.processResponse (node:internal/deps/undici/undici:5536:34)
    at node:internal/deps/undici/undici:5858:42
    at node:internal/process/task_queues:140:7
    at AsyncResource.runInAsyncScope (node:async_hooks:202:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  cause: TypeError: object2 is not iterable
      at action (node:internal/deps/undici/undici:1660:39)
      at action.next (<anonymous>)
      at Object.pull (node:internal/deps/undici/undici:1708:52)
      at ensureIsPromise (node:internal/webstreams/util:172:19)
      at readableStreamDefaultControllerCallPullIfNeeded (node:internal/webstreams/readablestream:1884:5)
      at node:internal/webstreams/readablestream:1974:7
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
}

I'm baffled about what's going on and what this error is about. Any ideas?
The following code correctly uploads the file (auto-generated from postman, some data <removed> for security) -

var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('type', 'Document');
data.append('name', 'ap_test_document.pdf');
data.append('file', fs.createReadStream('kX3bdHb1G/ap_test_document.pdf'));
data.append('entity_object_id', '<id>');

var config = {
  method: 'post',
  url: '<url>',
  headers: { 
    'Authorization': '<token>', 
    ...data.getHeaders()
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

Some help would be much appreciated.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

2025-02-13 03:57:36

您可以通过使用fs.ReadFile读取文件并将内容转换为blob,将文件附加到节点18本机fetch。

以下是我在打字稿(ymmv)中搅动的一些伪代码:

import fs from 'fs/promises';

async function createBlobFromFile(path: string): Promise<Blob> {
    const file = await fs.readFile(path);
    return new Blob([file]);
}

const path = '/path/to/file.txt';
const formData = new FormData();
formData.append('file', await createBlobFromFile(path), 'file.txt');

const response = await fetch('https://some.url', {
    method: 'POST',
    body: formData
});

You can append a file to the Node 18 native Fetch by reading the file with fs.readFile and converting the contents to a Blob.

The following is some pseudo-code I whipped up in TypeScript (YMMV):

import fs from 'fs/promises';

async function createBlobFromFile(path: string): Promise<Blob> {
    const file = await fs.readFile(path);
    return new Blob([file]);
}

const path = '/path/to/file.txt';
const formData = new FormData();
formData.append('file', await createBlobFromFile(path), 'file.txt');

const response = await fetch('https://some.url', {
    method: 'POST',
    body: formData
});
海未深 2025-02-13 03:57:36

您不能在node.js中使用fetch api,要么可以安装axiosnode-fetch

import fetch from 'node-fetch';

const body = {a: 1};

const response = await fetch('https://httpbin.org/post', {
    method: 'post',
    body: JSON.stringify(body),
    headers: {'Content-Type': 'application/json'}
});
const data = await response.json();

console.log(data);```

https://www.npmjs.com/package/node-fetch
https://www.npmjs.com/package/axios

You can't use the fetch API in Node.js, either you can install axios or node-fetch.

import fetch from 'node-fetch';

const body = {a: 1};

const response = await fetch('https://httpbin.org/post', {
    method: 'post',
    body: JSON.stringify(body),
    headers: {'Content-Type': 'application/json'}
});
const data = await response.json();

console.log(data);```

https://www.npmjs.com/package/node-fetch
https://www.npmjs.com/package/axios
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文