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


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é.


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


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

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

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


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)

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

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.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.