Как отправить сообщение в запрос с помощью node.js
Я пытаюсь опубликовать некоторый json для URL. Я видел различные другие вопросы об этом в stackoverflow, но ни один из них не казался ясным или не работал. Вот как я добрался, я изменил пример в api docs:
var http = require('http');
var google = http.createClient(80, 'server');
var request = google.request('POST', '/get_stuff',
{'host': 'sever', 'content-type': 'application/json'});
request.write(JSON.stringify(some_json),encoding='utf8'); //possibly need to escape as well?
request.end();
request.on('response', function (response) {
console.log('STATUS: ' + response.statusCode);
console.log('HEADERS: ' + JSON.stringify(response.headers));
response.setEncoding('utf8');
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
Когда я отправляю это на сервер, я получаю сообщение об ошибке, указывающее, что это не формат json или не utf8, каким они должны быть. Я попытался вытащить url запроса, но он равен нулю. Я только начинаю с nodejs, поэтому, пожалуйста, будьте милы.
Ответы
Ответ 1
Проблема заключается в том, что вы устанавливаете Content-Type в неправильном месте. Это часть заголовков запросов, у которых есть свой собственный ключ в объекте options, первый параметр метода request(). Здесь выполняется реализация с использованием ClientRequest() для одноразовой транзакции (вы можете сохранить createClient(), если вам нужно сделать несколько подключений к одному и тому же серверу):
var http = require('http')
var body = JSON.stringify({
foo: "bar"
})
var request = new http.ClientRequest({
hostname: "SERVER_NAME",
port: 80,
path: "/get_stuff",
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(body)
}
})
request.end(body)
Остальная часть кода в вопросе верна (request.on() и ниже).
Ответ 2
Джаммус понял это правильно. Если заголовок Content-Length не установлен, тело будет содержать некоторую длину в начале и 0 в конце.
Итак, когда я отправлял из Node:
{"email":"[email protected]","passwd":"123456"}
Сервер моих рельсов получал:
"2b {"email":"[email protected]","passwd":"123456"} 0 "
Rails не понял 2b, поэтому он не будет интерпретировать результаты.
Итак, для передачи параметров через JSON установите Content-Type в application/json и всегда указывайте Content-Length.
Ответ 3
Чтобы отправить JSON как POST во внешний API с помощью NodeJS... (и "http" )
var http = require('http');
var post_req = null,
post_data = '{"login":"toto","password":"okay","duration":"9999"}';
var post_options = {
hostname: '192.168.1.1',
port : '8080',
path : '/web/authenticate',
method : 'POST',
headers : {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Content-Length': post_data.length
}
};
post_req = http.request(post_options, function (res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('Response: ', chunk);
});
});
post_req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
post_req.write(post_data);
post_req.end();
Ответ 4
Это может не решить вашу проблему, но javascript не поддерживает именованные аргументы, поэтому вы говорите:
request.write(JSON.stringify(some_json),encoding='utf8');
Вы должны сказать:
request.write(JSON.stringify(some_json),'utf8');
Кодирование = назначает глобальную переменную, поэтому она действительна, но, вероятно, не делает того, что вы намереваетесь.
Ответ 5
Попробуйте включить длину содержимого.
var body = JSON.stringify(some_json);
var request = google.request('POST', '/get_stuff', {
host: 'server',
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'application/json'
});
request.write(body);
request.end();
Ответ 6
Существует очень хорошая библиотека, которая поддерживает отправку запроса POST в Nodejs:
Ссылка: https://github.com/mikeal/request
Пример кода:
var request = require('request');
//test data
var USER_DATA = {
"email": "[email protected]",
"password": "a075d17f3d453073853f813838c15b8023b8c487038436354fe599c3942e1f95"
}
var options = {
method: 'POST',
url: 'URL:PORT/PATH',
headers: {
'Content-Type': 'application/json'
},
json: USER_DATA
};
function callback(error, response, body) {
if (!error) {
var info = JSON.parse(JSON.stringify(body));
console.log(info);
}
else {
console.log('Error happened: '+ error);
}
}
//send request
request(options, callback);
Ответ 7
Вероятно, в тот момент, когда задавался этот вопрос, не существовало, вы могли бы использовать библиотеку более высокого уровня для обработки http-запросов, например https://github.com/mikeal/request. Node встроенный http-модуль слишком низкий для начинающих.
Модуль запросов Mikeal имеет встроенную поддержку для прямой обработки JSON (см. документацию, особенно https://github.com/mikeal/request#requestoptions-callback).
Ответ 8
var request = google.request(
'POST',
'/get_stuff',
{
'host': 'sever',
**'headers'**:
{
'content-type': 'application/json'
}
}
);