teruskan JSON ke HTTP POST Request

92

Saya mencoba membuat permintaan HTTP POST ke Google QPX Express API [1] menggunakan nodejs dan request [2].

Kode saya terlihat sebagai berikut:

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

Apa yang saya coba lakukan adalah meneruskan JSON menggunakan argumen multi bagian [3]. Tetapi alih-alih respons JSON yang tepat, saya mendapat kesalahan (400 tidak ditentukan).

Saat saya membuat permintaan menggunakan JSON dan API Key yang sama menggunakan CURL, ini berfungsi dengan baik. Jadi tidak ada yang salah dengan kunci API atau JSON saya.

Apa yang salah dengan kode saya?

EDIT :

contoh CURL bekerja:

i) Saya menyimpan JSON yang akan saya berikan ke permintaan saya ke dalam file bernama "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) kemudian, di terminal saya beralih ke direktori tempat file request.json yang baru dibuat berada dan dijalankan (myApiKey jelas merupakan singkatan dari API Key saya yang sebenarnya):

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] klien permintaan http yang dirancang untuk nodejs: https://www.npmjs.org/package/request [3] berikut adalah contoh yang saya temukan https://www.npmjs.org/package/request#multipart-related [4] QPX Express API menampilkan kesalahan 400 parse

Ronin
sumber
Coba removenig 'json: true' dari permintaan Anda
Baart
tidak membuat perbedaan. tapi sejauh yang saya tahu ini hanya menentukan bahwa responnya adalah json kan?
Ronin
Bisakah Anda menunjukkan baris perintah cURL yang berfungsi?
mscdex
Karena penasaran, mengapa Anda menggunakan multipart?
cloudfeet
@mscdex silakan lihat posting asli saya yang diperbarui
Ronin

Jawaban:

168

Saya pikir yang berikut seharusnya berhasil:

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

Dalam hal ini, Content-type: application/jsontajuk ditambahkan secara otomatis.

Tobi
sumber
1
Untuk alasan apa pun, titik akhir yang saya tekan tidak dapat membaca params menggunakan metode pertama (seolah-olah tidak dikirim) tetapi dapat melakukannya dengan metode kedua.
The Unknown Dev
Begitu juga dengan apa yang dikatakan Jamil. Saya dapatkan SyntaxError: Unexpected token &quot;<br> &nbsp; &nbsp;at parse (/home/malcolm/complice/node_modules/body-parser/lib/types/json.js:83:15)dengan metode pertama.
MalcolmOcean
@MalcolmOcean Itu karena tag <br> bukan konten JSON yang valid
Tobi
Saya mendapat kesalahan ini:, [ERR_STREAM_WRITE_AFTER_END]: write after endbagaimana cara memperbaikinya?
Mehdi Dehghani
18

Saya mengerjakan ini terlalu lama. Jawaban yang membantu saya ada di: send Content-Type: application / json post with node.js

Yang menggunakan format berikut:

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

Anda tidak menginginkan multibagian, tetapi permintaan POST "biasa" (dengan Content-Type: application/json) sebagai gantinya. Inilah yang Anda butuhkan:

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.dll
sumber
Saya mencoba ini, tetapi mendapatkan kesalahan lain: "400. Itu adalah kesalahan. Klien Anda telah mengeluarkan permintaan yang salah atau ilegal. Hanya itu yang kami tahu." untuk tanggapan lengkap, silakan kunjungi jsfiddle.net/f71opd7p
Ronin
4
@Tobi menurut dokumentasi permintaan dan kodenya , json: trueharus keduanya JSON.stringify() body dan JSON.parse() tanggapannya.
mscdex
Inilah jawabannya. Selain itu, Anda juga dapat menyalurkan responsrequest('xxx',{ json: true, body: req.body }).pipe(res).on('error', catchErr);
sidonaldson
Ini berhasil bagi saya ketika jawaban yang diterima tidak.
greg_diesel
Saya mendapat kesalahan ini:, [ERR_STREAM_WRITE_AFTER_END]: write after endbagaimana cara memperbaikinya?
Mehdi Dehghani
9

Sekarang dengan versi JavaScript baru (ECMAScript 6 http://es6-features.org/#ClassDefinition ) ada cara yang lebih baik untuk mengirimkan permintaan menggunakan nodejs dan permintaan Promise ( http://www.wintellect.com/devcenter/nstieglitz/5 -fitur-hebat-dalam-es6-harmoni )

Menggunakan perpustakaan: https://github.com/request/request-promise

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

klien:

//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 Urtan
sumber
3

Contoh.

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

Sebagai json: trueopsi penyisipan , setel isi ke representasi nilai JSON dan tambahkan "Content-type": "application/json"header. Selain itu, parsing isi respons sebagai JSON. TAUTAN

Youngmin Kim
sumber
2

Menurut dok: https://github.com/request/request

Contohnya adalah:

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

Saya pikir Anda mengirim objek di mana string diharapkan, ganti

body: requestData

oleh

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

saya rasa

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

Mendefinisikan seperti ini akan menjadi cara efektif untuk menulis kode Anda. Dan application / json akan ditambahkan secara otomatis. Tidak perlu secara khusus mendeklarasikannya.

Siddhartha Thota
sumber
0

Anda bisa meneruskan objek json sebagai badan (argumen ketiga) dari permintaan pengambilan.

ankur tiwari
sumber
1
Ini tidak memberikan jawaban atas pertanyaan tersebut. Setelah memiliki reputasi yang memadai, Anda dapat mengomentari kiriman apa pun ; sebaliknya, berikan jawaban sesuai panduan
Anna