使用Node.js和浏览器的HTTP POST原始二进制数据,不使用表单数据

时间:2017-07-18 23:05:07

标签: javascript node.js curl

所以我可以将图像转换为base64,然后使用JSON POST图像数据,这很方便,如下所示:

    curl -u "username:pwd" \
    -X PUT \
    -H "Content-Type: application/json" \
    -d '{"image":"my-base64-str-data"}' \
    http://maven.nabisco.com/artifactory/cdt-repo/folder/unique-image-id

但是,我的问题是 - 有没有办法发送原始二进制图像数据而不是编码为base64?怎么能用cURL或Node.js做到这一点?是否可以在HTTP请求中不使用表单数据的情况下发送文件或二进制数据?

然而,在一天结束时,我想从浏览器发布图像,在这种情况下,将图像编码为base64可能是唯一的方法吗?

1 个答案:

答案 0 :(得分:1)

卷曲

正如您在curl manpage上所看到的,此表单的上传是通过指定数据字符串完成的,并且可以使用--data-binary @/path/to/file语法直接从文件中完成:

  --data-binary <data>
          (HTTP) This posts data exactly as specified with no extra processing whatsoever.

          If you start the data with the letter @, the rest should be a filename.  Data is
          posted  in  a similar manner as --data-ascii does, except that newlines and car‐
          riage returns are preserved and conversions are never done.

          If this option is used several times, the ones following the first  will  append
          data as described in -d, --data.

如果图像仅以您的语言的二进制字符串形式提供,例如作为Node.js缓冲区,并且您不想访问文件系统,那么您可能必须通过将其封装在'个字符,并使用'等适当的转义序列替换字符串内的每个'\''字符,如果这让您感到不安,'"'"'。 (回想一下echo 'abc'"def"'ghi'abcdefghi作为一个单位回应。)

的Node.js

节点稍微宽容一点,因为它有一个显式的缓冲区类型,但它需要更多的构造才能使它工作。在这里,我将返回数据包装在Promise中以备不时之需:

const http = require("http");
function upload(image_buffer, image_id) {
  return new Promise((accept, reject) => {
    let options = {
      method: "PUT",
      hostname: "maven.nabisco.com",
      port: 80,
      path: "/artifactory/cdt-repo/folder/" + image_id,
      headers: {
        "Content-Type": "application/octet-stream",
        "Content-Length": image_buffer.length
      }
    };
    let data = [];
    let request = http.request(options, response => {
      response.on("data", chunk => data.push(chunk));
      response.on("end", () =>
        accept({
          headers: response.headers,
          statusCode: response.statusCode,
          data: Buffer.concat(data)
        })
      );
    });
    request.on("error", err => reject(err));

    request.write(image_buffer);
    request.end();
  });
}