Übergeben Sie JSON an HTTP POST Request

92

Ich versuche, mithilfe von nodejs und request [2] eine HTTP-POST-Anforderung an die Google QPX Express-API [1] zu senden .

Mein Code sieht wie folgt aus:

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

Ich versuche, den JSON mit dem mehrteiligen Argument [3] zu übergeben. Aber anstelle der richtigen JSON-Antwort habe ich einen Fehler erhalten (400 undefiniert).

Wenn ich stattdessen eine Anfrage mit demselben JSON und API-Schlüssel mit CURL mache, funktioniert dies einwandfrei. An meinem API-Schlüssel oder JSON ist also nichts auszusetzen.

Was ist los mit meinem Code?

EDIT :

funktionierendes CURL-Beispiel:

i) Ich habe den JSON, den ich an meine Anfrage übergeben würde, in einer Datei namens "request.json" gespeichert:

{
  "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) dann habe ich im Terminal in das Verzeichnis gewechselt, in dem sich die neu erstellte Datei request.json befand und ausgeführt wurde (myApiKey steht offensichtlich für meinen tatsächlichen API-Schlüssel):

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] Ein http-Anforderungsclient für NodeJS: https://www.npmjs.org/package/request [3] Hier ist ein Beispiel, das ich gefunden habe https://www.npmjs.org/package/request#multipart-related [4] Die QPX Express-API gibt einen 400-Analysefehler zurück

Ronin
quelle
Versuchen Sie, 'json: true' von Ihrer Anfrage zu entfernen
Baart
macht keinen Unterschied. aber soweit ich weiß, bedeutet dies nur, dass die Antwort ein json ist, oder?
Ronin
Können Sie die funktionierende cURL-Befehlszeile anzeigen?
mscdex
Warum verwenden Sie aus Neugier mehrteilig?
Wolkenfüße
@mscdex sehen Sie bitte meinen aktualisierten ursprünglichen Beitrag
Ronin

Antworten:

168

Ich denke, Folgendes sollte funktionieren:

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

In diesem Fall wird der Content-type: application/jsonHeader automatisch hinzugefügt.

Tobi
quelle
1
Aus irgendeinem Grund konnte der Endpunkt, den ich traf, die Parameter nicht mit der ersten Methode lesen (als ob sie nicht gesendet worden wären), sondern mit der zweiten Methode.
The Unknown Dev
Ebenso wie Jamil es gesagt hat. Ich habe SyntaxError: Unexpected token &quot;<br> &nbsp; &nbsp;at parse (/home/malcolm/complice/node_modules/body-parser/lib/types/json.js:83:15)mit der ersten Methode.
MalcolmOcean
@ MalcolmOcean Das liegt daran, dass ein <br> Tag kein gültiger JSON-Inhalt ist
Tobi
Ich habe diesen Fehler erhalten: [ERR_STREAM_WRITE_AFTER_END]: write after endWie kann ich ihn beheben?
Mehdi Dehghani
18

Ich habe zu lange daran gearbeitet. Die Antwort, die mir geholfen hat, war: send Content-Type: application / json post with node.js

Welches verwendet das folgende Format:

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

Sie möchten keine mehrteiligen, sondern eine "einfache" POST-Anfrage (mit Content-Type: application/json). Hier ist alles was Sie brauchen:

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
quelle
Ich habe dies versucht, aber einen weiteren Fehler erhalten: "400. Das ist ein Fehler. Ihr Client hat eine fehlerhafte oder illegale Anfrage gestellt. Das ist alles, was wir wissen." Für die vollständige Antwort besuchen Sie bitte jsfiddle.net/f71opd7p
Ronin
4
@Tobi gemäß der Anforderung Dokumentation und den Code , json: truesollten beide JSON.stringify() body und JSON.parse() die Antwort.
mscdex
Das ist die Antwort. Darüber hinaus können Sie auch die Antwort request('xxx',{ json: true, body: req.body }).pipe(res).on('error', catchErr);
leiten
Dies funktionierte für mich, wenn die akzeptierte Antwort nicht war.
Greg_diesel
Ich habe diesen Fehler erhalten: [ERR_STREAM_WRITE_AFTER_END]: write after endWie kann ich ihn beheben?
Mehdi Dehghani
9

Mit der neuen JavaScript-Version (ECMAScript 6 http://es6-features.org/#ClassDefinition ) gibt es jetzt eine bessere Möglichkeit, Anfragen mithilfe von NodeJS und Promise Request ( http://www.wintellect.com/devcenter/nstieglitz/5) zu senden -große-Merkmale-in-es6-Harmonie )

Bibliothek verwenden: https://github.com/request/request-promise

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

Klient:

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

Server:

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
quelle
3

Beispiel.

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

Setzt als Einfügeoption den json: trueBody auf die JSON-Darstellung des Werts und fügt einen "Content-type": "application/json"Header hinzu . Analysiert außerdem den Antworttext als JSON. VERKNÜPFUNG

Youngmin Kim
quelle
2

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

Das Beispiel ist:

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

Ich denke, Sie senden ein Objekt, wo eine Zeichenfolge erwartet wird, ersetzen

body: requestData

durch

body: JSON.stringify(requestData)
Baart
quelle
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
quelle
0

ich fühle

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

Eine solche Definition ist die effektive Methode zum Schreiben Ihres Codes. Und application / json sollte automatisch hinzugefügt werden. Es besteht keine Notwendigkeit, dies ausdrücklich zu deklarieren.

Siddhartha Thota
quelle
0

Sie können das json-Objekt als Hauptteil (drittes Argument) der Abrufanforderung übergeben.

ankur tiwari
quelle
1
Dies gibt keine Antwort auf die Frage. Sobald Sie einen ausreichenden Ruf haben, können Sie jeden Beitrag kommentieren . Geben Sie stattdessen Antworten gemäß Anleitung
Anna