Node.js - Array is converted to object when sent in HTTP GET request query

爱⌒轻易说出口 提交于 2019-12-20 05:52:31

问题


The following Node.js code:

var request = require('request');

var getLibs = function() {
    var options = { packages: ['example1', 'example2', 'example3'], os: 'linux', pack_type: 'npm' }

    request({url:'http://localhost:3000/package', qs:options}, 
    function (error , response, body) {
        if (! error && response.statusCode == 200) {
            console.log(body);
        } else if (error) {
            console.log(error);
        } else{
            console.log(response.statusCode);
        }
    });
}();

sends the following http GET request query that is received by like this:

{"packages"=>{"0"=>"example1", "1"=>"example2", "2"=>"example3"}, "os"=>"linux", "pack_type"=>"npm"}

How can I optimize this request to be received like this:

{"packages"=>["example1", "example2", "example3"], "os"=>"linux", "pack_type"=>"npm"}

Note. The REST API is built in Ruby on Rails


回答1:


If the array need to be received as it is, you can set useQuerystring as true:

UPDATE: list key in the following code example has been changed to 'list[]', so that OP's ruby backend can successfully parse the array.

Here is example code:

const request = require('request');

let data = {
  'name': 'John',
  'list[]': ['XXX', 'YYY', 'ZZZ']
};

request({
  url: 'https://requestb.in/1fg1v0i1',
  qs: data,
  useQuerystring: true
}, function(err, res, body) {
  // ...
});

In this way, when the HTTP GET request is sent, the query parameters would be:

?name=John&list[]=XXX&list[]=YYY&list[]=ZZZ

and the list field would be parsed as ['XXX', 'YYY', 'ZZZ']


Without useQuerystring (default value as false), the query parameters would be:

?name=John&list[][0]=XXX&list[][1]=YYY&list[][2]=ZZZ



回答2:


I finally found a fix. I used 'qs' to stringify 'options' with {arrayFormat : 'brackets'} and then concatinated to url ended with '?' as follows:

var request = require('request');
var qs1 = require('qs');

var getLibs = function() {
    var options = qs1.stringify({ 
        packages: ['example1', 'example2', 'example3'], 
        os: 'linux', 
        pack_type: 'npm' 
        },{
        arrayFormat : 'brackets'
    });


    request({url:'http://localhost:3000/package?' + options}, 
    function (error , response, body) {
        if (! error && response.statusCode == 200) {
            console.log(body);
        } else if (error) {
            console.log(error);
        } else{
            console.log(response.statusCode);
        }
    });
}();

Note: I tried to avoid concatenation to url, but all responses had code 400




回答3:


This problem can be solved using Request library itself. Request internally uses qs.stringify. You can pass q option to request which it will use to parse array params.

You don't need to append to url which leaves reader in question why that would have been done.

Reference: https://github.com/request/request#requestoptions-callback

const options = {
  method: 'GET',
  uri: 'http://localhost:3000/package',
  qs: {
    packages: ['example1', 'example2', 'example3'], 
    os: 'linux', 
    pack_type: 'npm' 
  },
  qsStringifyOptions: {
    arrayFormat: 'repeat' // You could use one of indices|brackets|repeat
  },
  json: true
};


来源:https://stackoverflow.com/questions/44710496/node-js-array-is-converted-to-object-when-sent-in-http-get-request-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!