J'essaie d'envoyer une requête HTTP POST à l'API google QPX Express [1] à l'aide de nodejs et demande [2].
Mon code se présente comme suit:
// 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, c'est de passer le JSON en utilisant l'argument multipart [3]. Mais au lieu de la réponse JSON appropriée, j'ai reçu une erreur (400 non définie).
Lorsque je fais une demande en utilisant les mêmes clés JSON et API en utilisant CURL, cela fonctionne correctement. Donc, il n'y a rien de mal avec ma clé API ou JSON.
Qu'est ce qui ne va pas avec mon code?
EDIT:
exemple de travail CURL:
i) J'ai sauvegardé le JSON que je voudrais transmettre à ma demande dans un fichier nommé "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) puis, dans le terminal, je suis passé dans le répertoire dans lequel le fichier request.json nouvellement créé a été localisé et exécuté (myApiKey représente évidemment ma clé API actuelle):
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 400 erreur d'analyse
Je pense que ce qui suit devrait fonctionner:
// fire request
request({
url: url,
method: "POST",
json: requestData
}, ...
Dans ce cas, l'en-tête Content-type: application/json
est automatiquement ajouté.
J'ai travaillé dessus trop longtemps. 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) { ...
Vous ne voulez pas plusieurs parties, mais une requête "simple" POST (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
});
Maintenant, avec la nouvelle version de JavaScript (ECMAScript 6 http://es6-features.org/#ClassDefinition ), il existe un meilleur moyen de soumettre des demandes à l'aide de nodejs et de la demande Promise ( http: // www.wintellect.com/devcenter/nstieglitz/5-great-features-in-es6-harmony )
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);
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);
});
Selon la 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)
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);
});
Lorsque vous insérez l'option json: true
, définissez body avec la représentation JSON de la valeur et ajoute l'en-tête "Content-type": "application/json"
. En outre, analyse le corps de la réponse au format JSON. LINK
Je ressens
var x = request.post({
uri: config.uri,
json: reqData
});
Définir comme ceci sera le moyen efficace d'écrire votre code. Et application/json devrait être ajouté automatiquement. Il n'est pas nécessaire de le déclarer spécifiquement.