简体   繁体   English

使用ID数组(Request.js)从网址中删除方括号

[英]Remove brackets from url with array of ids (Request.js)

I have an application with nodejs express who makes request but when I pass an array I am: 我有一个带有nodejs的应用程序来表达谁发出请求,但是当我传递一个数组时,我是:

Example: /foo?id=1&id=3&id=5 示例: /foo?id=1&id=3&id=5

How to remove '[]' ? 如何删除“ []”?

var requestQueryParams = {id: [1,3,5]}

var options = {
        url: 'www.test.com',
        headers: {'content-type': 'application/json', 'accept': 'application/json'},
        qs: requestQueryParams || {}
    };

request.get(options), function(){...}

result: www.test.com?id[0]=1&id[1]=3&id[2]=5 结果: www.test.com?id[0]=1&id[1]=3&id[2]=5

Request.js = https://www.npmjs.org/package/request Request.js = https://www.npmjs.org/package/request

Qs.js = https://www.npmjs.org/package/qs Qs.js = https://www.npmjs.org/package/qs

Qs.stringify({ a: ['b', 'c', 'd'] }); // 'a[0]=b&a[1]=c&a[2]=d'

Since some time now there is a better solution. 从现在开始已有更好的解决方案。 request uses qs per default to stringify the passed in qs object which also accepts options for formatting it. request默认情况下使用qs来对传入的qs对象进行字符串化,该对象还接受用于格式化它的选项。 One of this options is arrayFormat which accepts the following values: 此选项之一是arrayFormat ,它接受以下值:

  • indices : Default behavior. indices :默认行为。 Produces a string including the index: id[0]=foo&id[1]=bar&id[2]=baz . 产生一个包含索引的字符串: id[0]=foo&id[1]=bar&id[2]=baz Useful if you want to ensure the correct order. 如果您想确保正确的顺序很有用。
  • brackets : Produces a string with only brackets appended: id[]=foo&id[]=bar&id[]=baz . brackets :产生仅附加brackets的字符串: id[]=foo&id[]=bar&id[]=baz
  • repeat : Produces a string without any brackets: id=foo&id=bar&id=baz . repeat :产生一个不带方括号的字符串: id=foo&id=bar&id=baz Older services that don't support arrays may accept this but will then only use the last value. 不支持数组的较旧的服务可能会接受此方法,但只会使用最后一个值。

A options object with this would look like the following: 具有此选项的对象将如下所示:

const request = require('request');
const options = { 
  ...
  qs: {
    id: [ 'foo', 'bar', 'baz' ],
  },
  qsStringifyOptions: { arrayFormat: 'repeat' },
};
request(options);

See also https://github.com/request/request#requestoptions-callback , where that option is also mentioned. 另请参见https://github.com/request/request#requestoptions-callback ,其中也提到了该选项。

What do you want instead? 您想要什么呢? If you want www.test.com?id0=1&id1=3&id2=5 , then you need to give it a params object like this: 如果您希望www.test.com?id0=1&id1=3&id2=5 ,则需要为其提供一个params对象,如下所示:

var requestQueryParams = { id0: 1, id1: 3, id2: 5 }

If you already have an object that looks like { id: [1,2,3] } , then you need to convert that object into one like the above. 如果您已经有一个看起来像{ id: [1,2,3] } ,则需要将该对象转换为上面的对象。 You can do that in a for loop easily enough: 您可以轻松地在for循环中执行此操作:

var requestQueryParams = { id: [1,3,5] },
    newRequestQueryParams = {};

for(var i = 0; i < requestQueryParams.id.length; i++) {
  var paramName = "id" + i, // "id0", "id1", etc.
      id = requestQueryParams.id[i];

  newRequestQueryParams[paramName] = id;
}

console.log(newRequestQueryParams);
// => { id0: 1, id1: 3, id2: 5 }

Update: If you want a query string like id=1&id=3&id=5 (although this would be very strange, as I mention in my comment below), you can also do it in a for loop, as above, or you could do something like this: 更新:如果您想要一个查询字符串,例如id=1&id=3&id=5 (尽管这很奇怪,正如我在下面的评论中提到的那样),您也可以像上面那样在for循环中进行操作,也可以这样做像这样的东西:

var requestQueryParams = { id: [1,3,5] },
    queryStringParts = [], // an array this time
    queryString;

for(var i = 0; i < requestQueryParams.id.length; i++) {
  var param = "id=" + parseInt( requestQueryParams.id[i] );
  queryStringParts.push(param);
}
// queryStringParts is now [ "id=1", "id=3", "id=5" ]

queryString = queryStringParts.join("&")
console.log(queryString);
// => "id=1&id=3&id=5"

I used parseInt inside the for loop because I'm assuming the IDs are coming from an untrusted source (eg a user) and, since you're building a string manually instead of using a library that will encode the data for you, you want to prevent a malicious user from injecting arbitrary strings into your request. 我在for循环中使用了parseInt for因为我假设ID来自不受信任的来源(例如,用户),并且由于您是手动构建字符串而不是使用会为您编码数据的库,所以您想要防止恶意用户向您的请求中注入任意字符串。 You could also use encodeURIComponent , but it's overkill if IDs should always be numbers. 您也可以使用encodeURIComponent ,但是如果ID始终为数字,那就太过分了。

My Solution is override (request.Request.prototype.qs) 我的解决方案是覆盖(request.Request.prototype.qs)

var qs = require('qs'),
request = require('request'),
url = require('url');

var stringify;
var toString = Object.prototype.toString;

var isArray = Array.isArray || function (arr) {
return toString.call(arr) === '[object Array]';
};

var objectKeys = Object.keys || function (obj) {
var ret = [];
for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        ret.push(key);
    }
}
return ret;
};

var stringifyString = function (str, prefix) {
if (!prefix) throw new TypeError('stringify expects an object');
return prefix + '=' + encodeURIComponent(str);
};

var stringifyArray = function (arr, prefix) {
var ret = [];
if (!prefix) throw new TypeError('stringify expects an object');
for (var i = 0; i < arr.length; i++) {
    ret.push(stringify(arr[i], prefix));
}
return ret.join('&');
};

function stringifyObject(obj, prefix) {
var ret = [];
var keys = objectKeys(obj);
var key;

for (var i = 0, len = keys.length; i < len; ++i) {

    key = keys[i];

    if ('' === key) {
        continue;
    }

    if (null === obj[key]) {
        ret.push(encodeURIComponent(key) + '=');

    } else {
        ret.push(stringify(obj[key], prefix ? prefix + '[' + encodeURIComponent(key) + ']' :     encodeURIComponent(key)));
    }
}

return ret.join('&');
}

stringify = function (obj, prefix) {
if (isArray(obj)) {
    return stringifyArray(obj, prefix);
} else if ('[object Object]' === toString.call(obj)) {
    return stringifyObject(obj, prefix);
} else if ('string' === typeof obj) {
    return stringifyString(obj, prefix);
} else {
    return prefix + '=' + encodeURIComponent(String(obj));
}
};

And override prototype.qs : 并覆盖prototype.qs:

request.Request.prototype.qs = function (q, clobber) {
var base;

if (!clobber && this.uri.query) {
    base = qs.parse(this.uri.query)
}
else {
    base = {}
}

for (var i in q) {
    base[i] = q[i]
}

if (stringify(base) === '') {
    return this
}

this.uri = url.parse(this.uri.href.split('?')[0] + '?' + stringify(base));
this.url = this.uri;
this.path = this.uri.path;

return this;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM