Nodejs POST请求multipart/form-data

gio*_*lio 30 forms api post http node.js

我正试图通过POST请求上传照片 request module

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

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);
}
Run Code Online (Sandbox Code Playgroud)

问题是,这不起作用.我从测试服务器得到一个回复​​说它转储了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>
Run Code Online (Sandbox Code Playgroud)

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

gio*_*lio 26

经过一些研究,我决定使用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);
    });
});
Run Code Online (Sandbox Code Playgroud)


小智 14

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

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

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

@lildemon发布的解决方案可以解决这个问题:

  1. 生成FormData对象
  2. 得到它的长度
  3. 发出请求并显式设置表单对象和内容长度标头

以下是您的示例的修改版本:

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);
}
Run Code Online (Sandbox Code Playgroud)


wbe*_*rry 6

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

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

为了发现最终的选项参数,我必须深入到form-data. 但这给了我一个工作配置。(也许这是您缺少的东西,但这当然取决于服务器。)