Nodejs POST请求multipart / form-data

时间:2012-12-10 08:54:16

标签: forms api node.js http post

我正在尝试使用request module

通过POST请求上传照片

根据自述文件,我应该能够做到这一点

var r = request.post("http://posttestserver.com/post.php", requestCallback)
var form = r.form()
form.append("folder_id", "0");
form.append("filename", fs.createReadStream(path.join(__dirname, "image.png")));

function requestCallback(err, res, body) {
    console.log(body);
}

问题是,这不起作用。我从测试服务器得到一个回复​​,说它转储了0个变量。

我已经确认服务器处于这个小html页面的工作状态

<html>
    <body>
        <form action="http://posttestserver.com/post.php?dir=example" method="post" enctype="multipart/form-data">
            File: <input type="file" name="submitted">
            <input type="hidden" name="someParam" value="someValue"/>
            <input type="submit" value="send">
        </form>
    </body>
</html>

所以问题是,我对请求模块做错了什么?有没有更好的方法来发送multipart/form-data节点?

5 个答案:

答案 0 :(得分:25)

经过一些研究后,我决定使用restler module。这使得分段上传非常简单。

fs.stat("image.jpg", function(err, stats) {
    restler.post("http://posttestserver.com/post.php", {
        multipart: true,
        data: {
            "folder_id": "0",
            "filename": restler.file("image.jpg", null, stats.size, null, "image/jpg")
        }
    }).on("complete", function(data) {
        console.log(data);
    });
});

答案 1 :(得分:14)

所以我自己就完成了这个问题,这就是我所学到的:

事实证明,请求或表单数据都没有为生成的正文流设置内容长度标题。

以下是报告的问题:https://github.com/mikeal/request/issues/316

@lildemon发布的解决方案通过以下方式解决了这个问题:

  1. 生成FormData对象
  2. 得到它的长度
  3. 发出请求并明确设置表单对象和内容长度标题
  4. 以下是您的示例的修改版本:

    var request = require('request');
    var FormData = require('form-data');
    
    var form = new FormData();
    form.append("folder_id", "0");
    form.append("filename", fs.createReadStream(path.join(__dirname, "image.png")));
    
    form.getLength(function(err, length){
      if (err) {
        return requestCallback(err);
      }
    
      var r = request.post("http://posttestserver.com/post.php", requestCallback);
      r._form = form;     
      r.setHeader('content-length', length);
    
    });
    
    function requestCallback(err, res, body) {
      console.log(body);
    }
    

答案 2 :(得分:4)

我的工作代码完全符合您的问题所述,但有一个例外。我的文件内容以这种方式附加:

form.append('file', new Buffer(...),
    {contentType: 'image/jpeg', filename: 'x.jpg'});

要发现最终选项参数,我必须深入研究form-data的来源。但这给了我一个有效的配置。 (也许这就是你所缺少的,但当然这取决于服务器。)

答案 3 :(得分:3)

我还尝试了请求和表单数据模块,但无法上传文件。 你可以使用superagent,它有效:

http://visionmedia.github.io/superagent/#multipart-requests

var request = require('superagent');
var agent1 = request.agent();
agent1.post('url/fileUpload')
      .attach('file',__dirname + "/test.png")
      .end(function(err, res) {
          if (err) {
              console.log(err)
           }
       });

答案 4 :(得分:0)

尝试请求模块。它的工作方式与任何其他正常的帖子请求一样

var jsonUpload = {  };
var formData = {
    'file': fs.createReadStream(fileName),
    'jsonUpload': JSON.stringify(jsonUpload)
};
var uploadOptions = {
    "url": "https://upload/url",
    "method": "POST",
    "headers": {
        "Authorization": "Bearer " + accessToken
    },
    "formData": formData
}
var req = request(uploadOptions, function(err, resp, body) {
    if (err) {
        console.log('Error ', err);
    } else {
        console.log('upload successful', body)
    }
});