Nodejs POST请求multipart / form-data

我正尝试通过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); } 

问题是,这是行不通的。 我从testing服务器得到一个答复,说它倾销了0个variables。

我已经确认服务器处于这个小的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与节点?

经过一些更多的研究,我决定使用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); }); }); 

所以我刚刚做了这个自己摔跤,这是我学到了什么:

事实certificate,请求或表单数据都不会为正在生成的正文stream设置内容长度标题。

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

@lildemon发布的解决scheme通过以下方式获取:

  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); } 

我的工作代码完全符合你的问题,只有一个例外。 我的文件内容是这样附加的:

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

为了发现最终选项的论点,我不得不深入到form-data的来源。 但是这给了我一个工作的configuration。 (也许这是你错过了,但当然这取决于服务器。)

我也尝试请求和表单数据模块,无法上传文件。 你可以使用工作的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) } }); 

尝试请求模块。 它像任何其他正常的发布请求一样工作

 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) } });