web-dev-qa-db-fra.com

Comment publier une demande à l'aide de node.js

J'essaie de publier du json sur une URL. J'ai vu diverses autres questions à ce sujet sur stackoverflow mais aucune d'entre elles ne semblait claire ou ne fonctionnait. Voilà jusqu'où je suis arrivé, j'ai modifié l'exemple sur les docs api:

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

Lorsque je poste ceci sur le serveur, j'obtiens une erreur me disant que ce n'est pas au format json ou que ce n'est pas utf8, ce qu'ils devraient être. J'ai essayé de tirer l'URL de la demande mais elle est nulle. Je ne fais que commencer par nodejs, alors soyez gentil.

31
Mr JSON

Le problème est que vous définissez Content-Type au mauvais endroit. Il fait partie des en-têtes de requête, qui ont leur propre clé dans l'objet options, le premier paramètre de la méthode request (). Voici une implémentation utilisant ClientRequest () pour une transaction unique (vous pouvez conserver createClient () si vous devez établir plusieurs connexions avec le même serveur):

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)

Le reste du code de la question est correct (request.on () et ci-dessous).

40
Ankit Aggarwal

Jammus a bien compris. Si l'en-tête Content-Length n'est pas défini, le corps contiendra une sorte de longueur au début et un 0 à la fin.

Donc, quand j'envoyais depuis Node:

{"email":"[email protected]","passwd":"123456"}

mon Rails recevait:

"2b {"email":"[email protected]","passwd":"123456"} 0  "

Rails ne comprenait pas le 2b, donc il n'interpréterait pas les résultats.

Donc, pour passer des paramètres via JSON, définissez le Content-Type sur application/json et donnez toujours le Content-Length.

14
Jonathan O'Connor

Pour envoyer JSON en tant que POST vers une API externe avec NodeJS ... (et le module "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();
9
molokoloco

Il existe une très bonne bibliothèque qui prend en charge l'envoi de la requête POST dans Nodejs:

Lien: https://github.com/mikeal/request

Exemple de code:

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);
6
Dio Phung

Essayez d'inclure la longueur du contenu.

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();
4
jammus

Cela pourrait ne pas résoudre votre problème, mais javascript ne prend pas en charge les arguments nommés, alors où vous dites:

request.write(JSON.stringify(some_json),encoding='utf8');

Vous devriez dire:

request.write(JSON.stringify(some_json),'utf8');

L'encodage = est assigné à une variable globale, c'est donc une syntaxe valide mais ne faisant probablement pas ce que vous voulez.

3
RandomEtc

Probablement inexistant au moment où cette question a été posée, vous pouvez utiliser de nos jours une bibliothèque de niveau supérieur pour gérer les requêtes http, comme https://github.com/mikeal/request . Le module http intégré du nœud est trop bas pour les débutants.

Le module de demande de Mikeal a un support intégré pour gérer directement JSON (voir la documentation, en particulier https://github.com/mikeal/request#requestoptions-callback ).

3
jbmusso
var request = google.request(
  'POST',
  '/get_stuff',
  {
    'Host': 'sever',
    **'headers'**:
    {
      'content-type': 'application/json'
    }
  }
);
1
Jasper Fu