Отправка запроса от NodeJS приводит к пустой упаковке - PullRequest
0 голосов
/ 13 декабря 2018

Я пытаюсь сделать http-запрос к внешнему API из моего приложения NodeJS.Я попробовал два разных подхода, которые я нашел в Интернете, но оба не смогли с разными проблемами.Рабочая команда 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)
        }
    })
}

Когда я выполняю tcpdump наСервер API, я вижу, что полученный пакет выглядит аналогично тому, который был получен при выполнении команды curl, за исключением того, что для поля http.content_length_header установлено значение 0 (а сам conrent отсутствует).Когда я проверяю выходные данные отладки переменной 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, которую я нашел о том, как опубликовать строку.Тем не менее, один сбой с

Ошибка: подключите ECONNREFUSED 127.0.0.1:80

, хотя я не понимаю, почему он хочет привязаться к порту 80 на моем локальном хосте,Однако метод № 1 в любом случае будет предпочтительнее, это просто для полноты (И, может быть, кто-то знает умный ответ на этот вопрос также

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 голосов
/ 13 декабря 2018

В

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

данные неверны, они не являются действительными ключами для параметров запроса, это либо тело, либо форма.Это объясняет, почему данные тела не отправляются в запросе.

В вашем случае вам нужна форма

- при передаче объекта или строки запроса это устанавливает тело взначение строки запроса и добавляет заголовок 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.

...