passare JSON alla richiesta POST HTTP


92

Sto cercando di effettuare una richiesta HTTP POST all'API Google QPX Express [1] utilizzando nodejs e request [2].

Il mio codice appare come segue:

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

Quello che sto cercando di fare è passare il JSON utilizzando l'argomento multipart [3]. Ma invece della risposta JSON corretta ho ricevuto un errore (400 undefined).

Quando effettuo una richiesta utilizzando lo stesso JSON e la stessa chiave API utilizzando invece CURL, funziona correttamente. Quindi non c'è niente di sbagliato con la mia chiave API o JSON.

Cosa c'è di sbagliato nel mio codice?

MODIFICA :

esempio di CURL funzionante:

i) Ho salvato il JSON che avrei passato alla mia richiesta in un file chiamato "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) quindi, nel terminale sono passato alla directory in cui si trovava ed eseguito il file request.json appena creato (myApiKey sta ovviamente per la mia chiave API effettiva):

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 di richiesta http progettato per nodejs: https://www.npmjs.org/package/request [3] ecco un esempio che ho trovato https://www.npmjs.org/package/request#multipart-related [4] L' API QPX Express restituisce un errore di analisi 400


Prova a rimuovere "json: true" dalla tua richiesta
Baart

non fa differenza. ma per quanto ne so questo specifica solo che la risposta è un json giusto?
Ronin

Puoi mostrare la riga di comando cURL che funziona?
mscdex

Per curiosità, perché stai usando multipart?
nuvolosità

@mscdex per favore guarda il mio post originale aggiornato
Ronin

Risposte:


168

Penso che dovrebbe funzionare quanto segue:

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

In questo caso, l' Content-type: application/jsonintestazione viene aggiunta automaticamente.


1
Per qualsiasi motivo, l'endpoint che stavo colpendo non poteva leggere i parametri utilizzando il primo metodo (come se non fossero stati inviati) ma era in grado di farlo con il secondo metodo.
The Unknown Dev

Allo stesso modo di quello che ha detto Jamil. Ho ottenuto SyntaxError: Unexpected token &quot;<br> &nbsp; &nbsp;at parse (/home/malcolm/complice/node_modules/body-parser/lib/types/json.js:83:15)con il primo metodo.
MalcolmOcean

@MalcolmOcean Questo perché un tag <br> non è un contenuto JSON valido
Tobi,

Ho ricevuto questo errore: [ERR_STREAM_WRITE_AFTER_END]: write after endcome posso risolverlo?
Mehdi Dehghani

18

Ci ho lavorato troppo a lungo. La risposta che mi ha aiutato è stata: inviare Content-Type: application / json post con node.js

Che utilizza il seguente formato:

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

10

Non vuoi multipart, ma una richiesta POST "normale" (con Content-Type: application/json). Ecco tutto ciò di cui hai bisogno:

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

Ho provato ma ho ricevuto un altro errore: "400. È un errore. Il tuo client ha inviato una richiesta non valida o illegale. Questo è tutto ciò che sappiamo." per la risposta completa visita jsfiddle.net/f71opd7p per favore
Ronin

4
@Tobi secondo la documentazione della richiesta e il codice , json: truedovrebbero essere entrambi JSON.stringify() body e JSON.parse() la risposta.
mscdex

Questa è la risposta. Inoltre, puoi anche request('xxx',{ json: true, body: req.body }).pipe(res).on('error', catchErr);
inviare

Questo ha funzionato per me quando la risposta accettata non lo era.
greg_diesel

Ho ricevuto questo errore: [ERR_STREAM_WRITE_AFTER_END]: write after endcome posso risolverlo?
Mehdi Dehghani

9

Ora con la nuova versione di JavaScript (ECMAScript 6 http://es6-features.org/#ClassDefinition ) c'è un modo migliore per inviare richieste utilizzando nodejs e Promise request ( http://www.wintellect.com/devcenter/nstieglitz/5 -grande-caratteristiche-in-es6-armonia )

Utilizzo della libreria: https://github.com/request/request-promise

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

cliente:

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

3

Esempio.

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

Come json: trueopzione di inserimento , imposta il corpo sulla rappresentazione JSON del valore e aggiunge l' "Content-type": "application/json"intestazione. Inoltre, analizza il corpo della risposta come JSON. LINK


2

Secondo il doc: https://github.com/request/request

L'esempio è:

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

Penso che invii un oggetto in cui è prevista una stringa, sostituisci

body: requestData

di

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

io sento

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

Definire in questo modo sarà il modo più efficace per scrivere il codice. E application / json dovrebbe essere aggiunto automaticamente. Non è necessario dichiararlo specificamente.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.