Nodejs POST 请求多部分/表单数据

Posted

技术标签:

【中文标题】Nodejs POST 请求多部分/表单数据【英文标题】:Nodejs POST request multipart/form-data 【发布时间】:2012-11-27 16:08:45 【问题描述】:

我正在尝试通过带有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

【问题讨论】:

您是否也在导入表单数据库? 我不需要,它集成在请求模块中。 您的网址存在差异。一个是使用 https 方法,另一个是普通的 http。这是已经考虑过的事情吗? @limelights 这是一个复制错误。尽管posttestserver.com 似乎可以使用任何一种方式。 【参考方案1】:

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

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

【讨论】:

当将其发布到另一个服务的 url 时,readStream 属性从负载中消失,并且在接收端没有检测到请求上的事件。任何想法为什么?【参考方案2】:

我也尝试了请求和表单数据模块,但无法上传文件。 您可以使用有效的超级代理:

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

【讨论】:

这能回答问题吗? superagent 比 FormData、restler 或 axios 更容易使用。 @type/superagent 已经过时了。 (3.1 而不是 3.4)【参考方案3】:

所以我自己刚刚解决了这个问题,这就是我学到的:

事实证明,request 和 form-data 都没有为生成的正文流设置 content-length 标头。

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

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

    生成 FormData 对象 得到它的长度 发出请求并明确设置表单对象和内容长度标头

这是您的示例的修改版本:

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

【讨论】:

这对我很有帮助。经过长时间的搜索,我得到了这个。谢谢。【参考方案4】:

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

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

为了发现最终的选项参数,我不得不深入研究form-data 的来源。但这给了我一个工作配置。 (也许这是您所缺少的,但这当然取决于服务器。)

【讨论】:

我正要踏上这段旅程,但你帮我省了麻烦。泰! 7 年后,它仍然没有很好的记录【参考方案5】:

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

【讨论】:

确保导入部分的以下语句 var fs = require('fs'); 获取文件大小:var fs = require('fs'); var fileStats = fs.statSync('/myFile.jpg'); var fileSizeInBytes = fileStats["size"];控制台.log(fileStats); console.log(fileSizeInBytes); 如果文件大小超过 2 mb,我会收到错误消息。我应该在代码中修改什么? 许多 PHP 服务器的上传限制为 2mb。您可以直接使用表单上传更大的文件吗?如果不是,那么这是您的代码无法克服的服务器限制。

以上是关于Nodejs POST 请求多部分/表单数据的主要内容,如果未能解决你的问题,请参考以下文章

Javascript/AJAX POST 多部分/表单数据

Facebook API 使用带有多部分表单数据的 HTTP POST 请求的错误响应

使用 NodeJS 进行多部分文件上传

具有特定 JSON 要求的多部分表单数据 POST

多部分/表单数据请求失败。直播意外结束

PHP多部分表单数据PUT请求?