来自NodeJS的发布请求导致空包

时间:2018-12-13 13:00:06

标签: node.js http post request

我正在尝试从我的NodeJS应用程序向外部API发出http发布请求。我尝试了两种在网络上找到的不同方法,但是都因不同的问题而失败。产生正确请求的有效curl命令如下所示:

curl -d '  { "auth_token":"XXXXXXXXX",
            "hrows": [ {"cols": [ {"value":"Name 0"}, {"value":"Value 0"} ] } ],
            "rows":  [ {"cols": [ {"value":"Name 1"}, {"value":"Value 1"} ] },
                       {"cols": [ {"value":"Name 2"}, {"value":"Value 2"} ] },
                       {"cols": [ {"value":"Name 3"}, {"value":"Value 3"} ] },
                       {"cols": [ {"value":"Name 4"}, {"value":"Value 4"} ] } ]
          }' http://example.com:3030/widgets/alarms

1)尝试使用请求库发出请求。这不会在应用程序中引发错误,但是我在API服务器上收到一个空请求(是的,我要发送的内容是字符串)

var request = require('request');    
var test = "{\"auth_token\":\"XXXXXXXXXX\", \"hrows\": [ {\"cols\": [{\"value\":\"Loc Nr.\"},{\"value\":\"Address\"},{\"value\":\"Status\"}] } ],  \"rows\":  [ {\"cols\": [ {\"value\":\"Name 1\"}, {\"value\":\"Value 1\"} ] },   {\"cols\": [ {\"value\":\"Name 2\"}, {\"value\":\"Value 2\"} ] } ]}";
var wid = "alarms";

postRequest(wid,test);

function postRequest(widget, content) {
    var headers = {
        'User-Agent':       'Super Agent/0.0.1',
        'Content-Type':     'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(content)
    }   

    var options = {
        traditional: true,
        url: 'http://example.com:3030/widgets/'+widget,
        method: 'POST',
        headers: headers,
        data: content,
        contentType : "application/x-www-form-urlencoded"
    }   

    console.log(options);

    request.post(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log(body)
        }
    })
}

当我在API服务器上执行tcpdump时,我看到接收到的数据包看起来与执行curl命令时收到的数据包相似,只是将http.content_length_header字段设置为0(并且缺少内容本身) 。当我检查options变量的调试输出时,它看起来仍然可以:

{ traditional: true,
  url: 'http://example.com:3030/widgets/alarms',
  method: 'POST',
  headers:
   { 'User-Agent': 'Super Agent/0.0.1',
     'Content-Type': 'application/x-www-form-urlencoded',
     'Content-Length': 243 },
  data:
   '{"auth_token":"XXXXXXXXX", "hrows": [ {"cols": [{"value":"Loc Nr."},{"value":"Address"},{"value":"Status"}] } ],  "rows":  [ {"cols": [ {"value":"Name 1"}, {"value":"Value 1"} ] },\t{"cols": [ {"value":"Name 2"}, {"value":"Value 2"} ] } ]}',
  contentType: 'application/x-www-form-urlencoded' }

您可以看到内容长度和数据都存在,但是没有在收到的数据包中显示(请参阅随附的屏幕快照,其中一个来自curl命令,另一个来自NodeJS请求,均在API服务器上捕获) Not working example And the working curl one

知道为什么会这样吗?

2)我尝试的第二种方法是从我发现有关如何发布字符串的Stackoverflow Post中获得。但是那个失败了

  

错误:连接ECONNREFUSED 127.0.0.1:80

尽管我不明白为什么它要绑定到我的本地主机上的端口80,但是无论如何方法#1仍然是首选,这只是为了完整性(也许有人也对此很聪明地回答了< / p>

var querystring = require('querystring');
var http = require('http');
var fs = require('fs');
var test = "{\"auth_token\":\"XXXXXXXX\", \"hrows\": [ {\"cols\": [{\"value\":\"Loc Nr.\"},{\"value\":\"Address\"},{\"value\":\"Status\"}] } ],  \"rows\":  [ {\"cols\": [ {\"value\":\"Name 1\"}, {\"value\":\"Value 1\"} ] }, {\"cols\": [ {\"value\":\"Name 2\"}, {\"value\":\"Value 2\"} ] } ]}";
var wid = "alarms";

postRequest(wid,test);

function postRequest(widget, content) {                     
    var headers = {
        'User-Agent':       'Super Agent/0.0.1',
        'Content-Type':     'application/x-www-form-urlencoded',
        'Content-Length':   Buffer.byteLength(content)
    }   

    var options = {
        url: 'http://example.com:3030/widgets/'+widget,
        method: 'POST',
        headers: headers,
    }   

    var pdata = querystring.stringify(content);
    console.log(pdata)
    console.log(Object.prototype.toString.call(pdata));


    var post_req = http.request(options, function() {
      });

      // post the data
      post_req.write(pdata);
      post_req.end();

}

感谢任何有用的提示(或者提示如何使用破折号API触发破折工作,但据我所知这是不可能的,所以我必须坚持使用这些API调用:))

1 个答案:

答案 0 :(得分:1)

出现错误

var options = {
    traditional: true,
    url: 'http://example.com:3030/widgets/'+widget,
    method: 'POST',
    headers: headers,
    data: content,
    contentType : "application/x-www-form-urlencoded"
}   

数据不是请求选项上的有效键,它可以是正文或形式。那会 解释为什么在请求中没有发送正文数据。

如果您要填写表格

  

form-传递对象或查询字符串时,会将主体设置为值的查询字符串表示形式,并添加Content-type:   application / x-www-form-urlencoded标头。如果不传递任何选项,   返回FormData实例(并通过管道传递给请求)。参见“表格”   上面的部分。

var options = {
    traditional: true,
    url: 'http://example.com:3030/widgets/'+widget,
    method: 'POST',
    headers: headers,
    form: content,
    contentType : "application/x-www-form-urlencoded"
}

有关更多详细信息,请参见https://www.npmjs.com/package/request#requestoptions-callback