passer JSON à HTTP POST Request

92

J'essaye de faire une requête HTTP POST à ​​l'API google QPX Express [1] en utilisant nodejs et request [2].

Mon code ressemble à ceci:

    // create http request client to consume the QPX API
    var request = require("request")

    // JSON to be passed to the QPX Express API
    var requestData = {
        "request": {
            "slice": [
                {
                    "origin": "ZRH",
                    "destination": "DUS",
                    "date": "2014-12-02"
                }
            ],
            "passengers": {
                "adultCount": 1,
                "infantInLapCount": 0,
                "infantInSeatCount": 0,
                "childCount": 0,
                "seniorCount": 0
            },
            "solutions": 2,
            "refundable": false
        }
    }

    // QPX REST API URL (I censored my api key)
    url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=myApiKey"

    // fire request
    request({
        url: url,
        json: true,
        multipart: {
            chunked: false,
            data: [
                {
                    'content-type': 'application/json',
                    body: requestData
                }
            ]
        }
    }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
            console.log(body)
        }
        else {

            console.log("error: " + error)
            console.log("response.statusCode: " + response.statusCode)
            console.log("response.statusText: " + response.statusText)
        }
    })

Ce que j'essaie de faire est de passer le JSON en utilisant l'argument multipart [3]. Mais au lieu de la bonne réponse JSON, j'ai eu une erreur (400 indéfini).

Lorsque je fais une demande en utilisant le même JSON et la même clé API en utilisant CURL à la place, cela fonctionne bien. Il n'y a donc rien de mal avec ma clé API ou JSON.

Qu'est ce qui ne va pas avec mon code?

MODIFIER :

exemple de travail CURL:

i) J'ai enregistré le JSON que je passerais à ma requête dans un fichier appelé "request.json":

{
  "request": {
    "slice": [
      {
        "origin": "ZRH",
        "destination": "DUS",
        "date": "2014-12-02"
      }
    ],
    "passengers": {
      "adultCount": 1,
      "infantInLapCount": 0,
      "infantInSeatCount": 0,
      "childCount": 0,
      "seniorCount": 0
    },
    "solutions": 20,
    "refundable": false
  }
}

ii) ensuite, dans le terminal, je suis passé au répertoire dans lequel le fichier request.json nouvellement créé était situé et exécuté (myApiKey représente évidemment ma clé API réelle):

curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=myApiKey

[1] https://developers.google.com/qpx-express/ [2] un client de requête http conçu pour nodejs: https://www.npmjs.org/package/request [3] voici un exemple que j'ai trouvé https://www.npmjs.org/package/request#multipart-related [4] L'API QPX Express renvoie une erreur d'analyse 400

Ronin
la source
Essayez de supprimer 'json: true' de votre demande
Baart
ne fait aucune différence. mais pour autant que je sache, cela précise seulement que la réponse est un droit json?
Ronin
Pouvez-vous afficher la ligne de commande cURL qui fonctionne?
mscdex
Par curiosité, pourquoi utilisez-vous le multipart?
cloudfeet
@mscdex s'il vous plaît voir mon message original mis à jour
Ronin

Réponses:

168

Je pense que ce qui suit devrait fonctionner:

// fire request
request({
    url: url,
    method: "POST",
    json: requestData
}, ...

Dans ce cas, l'en- Content-type: application/jsontête est automatiquement ajouté.

Tobi
la source
1
Pour une raison quelconque, le point de terminaison sur lequel je frappais ne pouvait pas lire les paramètres en utilisant la première méthode (comme s'ils n'avaient pas été envoyés) mais a pu le faire avec la deuxième méthode.
The Unknown Dev
De même à ce que Jamil a dit. J'ai eu SyntaxError: Unexpected token &quot;<br> &nbsp; &nbsp;at parse (/home/malcolm/complice/node_modules/body-parser/lib/types/json.js:83:15)avec la première méthode.
MalcolmOcean
@MalcolmOcean C'est parce qu'une balise <br> n'est pas un contenu JSON valide
Tobi
J'ai cette erreur:, [ERR_STREAM_WRITE_AFTER_END]: write after endcomment puis-je la corriger?
Mehdi Dehghani
18

J'ai travaillé trop longtemps dessus. La réponse qui m'a aidé était à: envoyer Content-Type: application / json post avec node.js

Qui utilise le format suivant:

request({
    url: url,
    method: "POST",
    headers: {
        "content-type": "application/json",
        },
    json: requestData
//  body: JSON.stringify(requestData)
    }, function (error, resp, body) { ...
DanBaker
la source
10

Vous ne voulez pas en plusieurs parties, mais une requête POST "simple" (avec Content-Type: application/json) à la place. Voici tout ce dont vous avez besoin:

var request = require('request');

var requestData = {
  request: {
    slice: [
      {
        origin: "ZRH",
        destination: "DUS",
        date: "2014-12-02"
      }
    ],
    passengers: {
      adultCount: 1,
      infantInLapCount: 0,
      infantInSeatCount: 0,
      childCount: 0,
      seniorCount: 0
    },
    solutions: 2,
    refundable: false
  }
};

request('https://www.googleapis.com/qpxExpress/v1/trips/search?key=myApiKey',
        { json: true, body: requestData },
        function(err, res, body) {
  // `body` is a js object if request was successful
});
mscdex
la source
J'ai essayé ceci mais j'ai obtenu une autre erreur: "400. C'est une erreur. Votre client a émis une demande incorrecte ou illégale. C'est tout ce que nous savons." pour la réponse complète, visitez jsfiddle.net/f71opd7p s'il vous plaît
Ronin
4
@Tobi selon la documentation de la demande et le code , json: truedevrait à la fois JSON.stringify() body et JSON.parse() la réponse.
mscdex
C'est la réponse. Suite à cela, vous pouvez également canaliser la réponserequest('xxx',{ json: true, body: req.body }).pipe(res).on('error', catchErr);
sidonaldson
Cela a fonctionné pour moi lorsque la réponse acceptée n'était pas.
greg_diesel
J'ai cette erreur:, [ERR_STREAM_WRITE_AFTER_END]: write after endcomment puis-je la corriger?
Mehdi Dehghani
9

Désormais, avec la nouvelle version JavaScript (ECMAScript 6 http://es6-features.org/#ClassDefinition ), il existe un meilleur moyen de soumettre des requêtes en utilisant nodejs et Promise request ( http://www.wintellect.com/devcenter/nstieglitz/5 -grandes-fonctionnalités-en-harmonie-es6 )

Utilisation de la bibliothèque: https://github.com/request/request-promise

npm install --save request
npm install --save request-promise

client:

//Sequential execution for node.js using ES6 ECMAScript
var rp = require('request-promise');

rp({
    method: 'POST',
    uri: 'http://localhost:3000/',
    body: {
        val1 : 1,
        val2 : 2
    },
    json: true // Automatically stringifies the body to JSON
}).then(function (parsedBody) {
        console.log(parsedBody);
        // POST succeeded...
    })
    .catch(function (err) {
        console.log(parsedBody);
        // POST failed...
    });

serveur:

var express = require('express')
    , bodyParser = require('body-parser');

var app = express();

app.use(bodyParser.json());

app.post('/', function(request, response){
    console.log(request.body);      // your JSON

    var jsonRequest = request.body;
    var jsonResponse = {};

    jsonResponse.result = jsonRequest.val1 + jsonRequest.val2;

    response.send(jsonResponse);
});


app.listen(3000);
Evalds Urtans
la source
3

Exemple.

var request = require('request');

var url = "http://localhost:3000";

var requestData = {
    ...
} 

var data = {
    url: url,
    json: true,
    body: JSON.stringify(requestData)
}

request.post(data, function(error, httpResponse, body){
    console.log(body);
});

En tant json: truequ'option d' insertion , définit le corps sur la représentation JSON de la valeur et ajoute un en- "Content-type": "application/json"tête. En outre, analyse le corps de la réponse en tant que JSON. LIEN

Youngmin Kim
la source
2

Selon doc: https://github.com/request/request

L'exemple est:

  multipart: {
      chunked: false,
      data: [
        {
          'content-type': 'application/json', 
          body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
        },
      ]
    }

Je pense que vous envoyez un objet où une chaîne est attendue, remplacez

body: requestData

par

body: JSON.stringify(requestData)
Baart
la source
2
       var request = require('request');
        request({
            url: "http://localhost:8001/xyz",
            json: true,
            headers: {
                "content-type": "application/json",
            },
            body: JSON.stringify(requestData)
        }, function(error, response, body) {
            console.log(response);
        });
Ashish Gupta
la source
0

Je ressens

var x = request.post({
       uri: config.uri,
       json: reqData
    });

Une telle définition sera le moyen efficace d'écrire votre code. Et application / json devrait être automatiquement ajouté. Il n'est pas nécessaire de le déclarer spécifiquement.

Siddhartha Thota
la source
0

vous pouvez passer l'objet json comme corps (troisième argument) de la requête d'extraction.

Ankur tiwari
la source
1
Cela ne répond pas à la question. Une fois que vous aurez une réputation suffisante, vous pourrez commenter n'importe quel message ; au lieu de cela, fournissez des réponses selon le guide
Anna