Отправка запроса от NodeJS приводит к пустому пакету

Я пытаюсь отправить 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.info(options);

    request.post(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.info(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) Отправка запроса от NodeJS приводит к пустому пакетуОтправка запроса от NodeJS приводит к пустому пакету

Есть идеи, почему это происходит?

2) Второй способ, который я пробовал, был из сообщения Stackoverflow, которое я нашел о том, как опубликовать строку. Однако тот не справляется с

Error: connect 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.info(pdata)
    console.info(Object.prototype.toString.call(pdata));


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

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

}

Спасибо за любые полезные подсказки (или подсказку, как запустить лихую работу с помощью лихого API, но, насколько я понимаю, это невозможно, поэтому я должен придерживаться этих вызовов API :))

Какую библиотеку запросов вы используете?

Dennis Ruiter 13.12.2018 14:15

упс, просто посмотрите, что в моем первом фрагменте кода отсутствовала требуемая часть, отредактировал ее. npmjs.com/package/request

Nils Rehwald 13.12.2018 14:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Что-то идет не так

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

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

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

form - when passed an object or a querystring, this sets body to a querystring representation of value, and adds Content-type: application/x-www-form-urlencoded header. When passed no options, a FormData instance is returned (and is piped to request). See "Forms" section above.

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 для более подробной информации.

Argh, rtfm: D Спасибо, я полностью полагался на учебник в Интернете с использованием ключа данных. Так я получу данные, спасибо!

Nils Rehwald 17.12.2018 09:02

PS: Для варианта использования обновления виджета в Dashing необходимо использовать клавишу «body». На всякий случай кто-то наткнулся на этот вопрос по той же причине, что и я;)

Nils Rehwald 17.12.2018 09:20

Другие вопросы по теме