【问题标题】:how can I send an image binary via post to an API? nodejs如何通过 post 将图像二进制文件发送到 API?节点
【发布时间】:2021-04-23 20:00:09
【问题描述】:

我得到这样的图像二进制文件:

axios.get("image-url.jpg")

我需要使用响应向另一台服务器发出新的 POST 请求

  const form = new FormData();
  const url = "post-url-here.com";
  form.append(
    "file",
    new ReadableStream(Buffer.from(file)),
    "image-test.jpg"
  );
  const config = {
    headers: {
      ...form.getHeaders(),
      Authorization:
        "Bearer token-here",
    },
  };
  axios.post(url, form, config);

不幸的是,这不起作用。我得到的回应是:

data: {
  message: 'This file is not compatible with the picture engine, please try another one',
  error: 'bad_request',
  status: 400,
  cause: []
}

我怎样才能正确地做到这一点?

编辑: form.getheaders 正在将此标头添加到请求中:

'content-type': 'multipart/form-data; boundary=--------------------------783115116498484087556627'

所有请求标头:

headers: {
  Accept: 'application/json, text/plain, */*',
  'Content-Type': 'multipart/form-data; boundary=--------------------------918731250556909112992344',
  Authorization: 'Bearer token-here',
  'User-Agent': 'axios/0.21.1'
},

所有请求信息:

_header: 'POST /pictures/items/upload HTTP/1.1\r\n' +
  'Accept: application/json, text/plain, */*\r\n' +
  'Content-Type: multipart/form-data; boundary=--------------------------116660171215340291632150\r\n' +
  'Authorization: Bearer token-here\r\n' +
  'User-Agent: axios/0.21.1\r\n' +
  'Host: api.mercadolibre.com\r\n' +
  'Connection: close\r\n' +
  'Transfer-Encoding: chunked\r\n' +
  '\r\n',

【问题讨论】:

  • 您是否将图像“image-url.jpg”保存在硬盘上,然后选择将其发布到服务器或需要即时执行?例如:从 url 获取图像 -> 发布到服务器而不保存图像?
  • 调试 form.getHeaders() ,或者使用监听套接字记录整个 Post 请求,我们可以查看整个 Post resquest header
  • 是的,我确实需要即时进行。我正在编辑添加 .getHeaders 信息的问题
  • content-type 只是整个 Header 的一部分。请把整个标题贴出来好吗?
  • 是的,这是 .getHeaders 生成的唯一标头。我正在再次编辑请求的所有最终标头

标签: javascript node.js file-upload multipart


【解决方案1】:

POST Header 示例:

POST /video-upload/ HTTP/1.1
Host: your host 
User-Agent: axios/0.21.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------219493771727403213993181042749
Content-Length: 99211703
Connection: keep-alive

如您所见,有一些重要的部分,例如:

POST /the-url/ HTTP/1.1
Host: your host 
Content-Length: the length in bytes of your image 
Content-Type: multipart/form-data; boundary=---------------------------219493771727403213993181042749
Connection: keep-alive

所以您的脚本不会读取图像,您的标头已损坏,因为服务器的状态:400 响应说。

试试这个(伪代码):

const axios = require('axios');
const fs = require('fs');

var im_config = {
    responseType: 'stream'
};

let im_url =  'image-url' ;

async function getImage() {
    let resp = await axios.get(im_url, im_config);
    //save the image
    resp.data.pipe(fs.createWriteStream('test-image.jpg'));
}

getImage().then(function(result){

  console.log(result); 

  const form = new FormData();
  const url = "server url where send the form ";

  // interesting part 
  form.append('image', 'test-image.jpg');   
  axios.post(url, form, your-config);

});

成功了!好的。

要即时执行此操作,请尝试在不保存图像的情况下从“result”或“resp”获取下载图像的引用。

否则在 POST 完成后取消链接下载的图像。

fs.unlink('test-image.jpg', (err) => {
  if (err) {
    console.error(err)
    return
  }
}

【讨论】:

  • 我从我的 axios 请求中添加了更多信息。但我仍然找不到任何内容长度。这可能是问题吗?
  • 我们可以尝试下载图像,保存,然后将其附加到表单并发布到服务器。如果我们在标头中获得更多数据,我们就有可能在之后即时执行此操作。请参阅编辑后的答案。
  • 是的,它奏效了。唯一的问题是我必须保存和删除它们,否则我会遇到存储问题。您能在不保存任何文件的情况下即时查看其他方法吗?
  • 我认为您也需要销毁缓冲区,除非 nodejs 在脚本结束时为您执行此操作。但是在 POST OK 响应之后似乎很简单,取消链接/删除/删除下载的图像。因此,完成了一项任务并且脚本有效。
  • 请在您的问题标题中添加“Nodejs”
猜你喜欢
  • 2019-11-24
  • 1970-01-01
  • 2011-12-13
  • 2014-03-31
  • 2020-09-29
  • 1970-01-01
  • 2022-01-23
  • 2021-02-27
  • 2012-02-18
相关资源
最近更新 更多