使用 xmlhhtprequest 的异步表单数据 POST 请求

Asynchronous form-data POST request with xmlhhtprequest

我正在尝试将文件上传到 Octoprint 的 REST Api,这应该通过使用 Content-Type: multipart/form-data 发送 POST 请求来完成 (http://docs.octoprint.org/en/master/api/fileops.html#upload-file)

我正在使用 NodeJS 和两个库,XmlHttpRequest 和表单数据。尝试时:

    var xhr = new xmlhttprequest() ;
    var form = new formData() ;
    form.append('exampleKey', 'exampleValue');
    xhr.open("POST","octopi.local/api/local", true) ;
    xhr.setRequestHeader("Content-Type","multipart/form-data") ;
    xhr.send(form) ;

我在 xhr.send 行收到错误:

    TypeError: first argument must be a string or Buffer

如果我使用 xhr.open("POST",url,false) 发出同步请求,则此错误消失。

为什么会这样?有没有办法把它变成异步请求?

EDIT 实际上,我不太了解文档。我想我应该使用 form.append("filename", filepath, "exampleName") 设置要上传的文件,但我不确定。事实上,我注意到即使我尝试简化请求,但没有发送任何文件,我也会收到 TypeError。

EDIT2这是修改后的代码,里面returns同样的错误:

    var XMLHttpRequest=require('xmlhttprequest').XMLHttpRequest ;
    var FormData = require('form-data');

    var data = new FormData();
    data.append("key","value" );

    var xhr = new XMLHttpRequest();
    xhr.open('POST', "octopi.local/api/files/");
    xhr.send(data);

您的代码中似乎有一些拼写错误。请改用下面的代码片段。根据您的需要更换相关部件

var fileToUpload = document.getElementById('input').files[0];
var data = new FormData();
data.append("myfile", fileToUpload);

var xhr = new XMLHttpRequest();
xhr.open('POST', "upload_endpoint");
xhr.send(data);

折腾了很久,终于上传了一个文件。如果您使用 NodeJS,请不要依赖 MDN 文档:它告诉库应该做什么,而不是它们在节点平台上实际可以做什么。您应该只关注 GitHub 上可用的文档。

目前似乎无法使用 XMLHttpRequest 发送表单:我尝试使用 JSON.stringify(form) 但 wireshark 告诉我该请求不是 multipart/formdata 请求。

如果您想上传文件,您应该使用 'request' 模块。以下对我有用:

exports.unwrappeduploadToOctoprint = function(){
  "use strict" ;
  var form ={
    file: {
           value: fs.readFileSync(__dirname+'/test2.gcode'),
           options: { filename: 'test2.gcode'}
         }
  };

  var options = {
    method: 'POST',
    url: 'http://192.168.1.24/api/files/local',
    headers: { 'x-api-key': 'E0A2518FB11B40F595FC0068192A1AB3'},
    formData: form
  };

  var req = request(options, function (error, response, body) {
    if (error) throw new Error(error);
    console.log(body);
  });
};