pasar JSON a HTTP POST Request


92

Estoy intentando realizar una solicitud HTTP POST a la API de Google QPX Express [1] utilizando nodejs y la solicitud [2].

Mi código se ve como sigue:

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

Lo que estoy tratando de hacer es pasar el JSON usando el argumento multiparte [3]. Pero en lugar de la respuesta JSON adecuada, recibí un error (400 indefinido).

Cuando hago una solicitud usando el mismo JSON y API Key usando CURL en su lugar, funciona bien. Entonces, no hay nada de malo con mi clave API o JSON.

¿Qué pasa con mi código?

EDITAR :

ejemplo de CURL de trabajo:

i) Guardé el JSON que pasaría a mi solicitud en un archivo llamado "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) luego, en la terminal cambié al directorio en el que se ubicó y ejecutó el archivo request.json recién creado (myApiKey significa mi clave API real obviamente):

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 cliente de solicitud http diseñado para nodejs: https://www.npmjs.org/package/request [3] aquí hay un ejemplo que encontré https://www.npmjs.org/package/request#multipart-related [4] La API de QPX Express devuelve un error de análisis 400


Intente eliminar 'json: true' de su solicitud
Baart

no hace la diferencia. pero hasta donde yo sé, esto solo especifica que la respuesta es un json, ¿verdad?
Ronin

¿Puede mostrar la línea de comando cURL que funciona?
mscdex

Por curiosidad, ¿por qué utiliza varias partes?
Cloudfeet

@mscdex, por favor vea mi publicación original actualizada
Ronin

Respuestas:


168

Creo que lo siguiente debería funcionar:

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

En este caso, el Content-type: application/jsonencabezado se agrega automáticamente.


1
Por alguna razón, el punto final al que estaba accediendo no pudo leer los parámetros usando el primer método (como si no se hubieran enviado), pero pudo hacerlo con el segundo método.
The Unknown Dev

Asimismo, a lo que dijo Jamil. Conseguí SyntaxError: Unexpected token &quot;<br> &nbsp; &nbsp;at parse (/home/malcolm/complice/node_modules/body-parser/lib/types/json.js:83:15)con el primer método.
MalcolmOcean

@MalcolmOcean Eso es porque una etiqueta de <br> no es un contenido JSON válido
Tobi

Recibí este error: [ERR_STREAM_WRITE_AFTER_END]: write after end¿cómo puedo solucionarlo?
Mehdi Dehghani

18

Trabajé en esto durante demasiado tiempo. La respuesta que me ayudó fue: enviar Content-Type: application / json post con node.js

Que usa el siguiente formato:

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

10

No desea varias partes, sino una solicitud POST "simple" (con Content-Type: application/json) en su lugar. Aquí tienes todo lo que necesitas:

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

Intenté esto, pero obtuve otro error: "400. Eso es un error. Su cliente ha emitido una solicitud incorrecta o ilegal. Eso es todo lo que sabemos". para obtener la respuesta completa, visite jsfiddle.net/f71opd7p por favor
Ronin

4
@Tobi de acuerdo con la documentación de la solicitud y el código , json: truetanto JSON.stringify() body como JSON.parse() la respuesta.
mscdex

Esta es la respuesta. Además, también puede canalizar la respuestarequest('xxx',{ json: true, body: req.body }).pipe(res).on('error', catchErr);
sidonaldson

Esto funcionó para mí cuando la respuesta aceptada no lo era.
greg_diesel

Recibí este error: [ERR_STREAM_WRITE_AFTER_END]: write after end¿cómo puedo solucionarlo?
Mehdi Dehghani

9

Ahora, con la nueva versión de JavaScript (ECMAScript 6 http://es6-features.org/#ClassDefinition ) hay una mejor manera de enviar solicitudes utilizando nodejs y la solicitud de Promise ( http://www.wintellect.com/devcenter/nstieglitz/5 -grandes-funciones-en-es6-harmonia )

Usando la biblioteca: 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...
    });

servidor:

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

Ejemplo.

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

Como json: trueopción de inserción , establece el cuerpo en la representación JSON del valor y agrega el "Content-type": "application/json"encabezado. Además, analiza el cuerpo de la respuesta como JSON. ENLACE


2

Según doc: https://github.com/request/request

El ejemplo es:

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

Creo que envías un objeto donde se espera una cadena, reemplaza

body: requestData

por

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

siento

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

Definir así será la forma efectiva de escribir su código. Y la aplicación / json debería agregarse automáticamente. No es necesario declararlo específicamente.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.