繁体   English   中英

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

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

我有一个带有nodejs的应用程序来表达谁发出请求,但是当我传递一个数组时,我是:

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

如何删除“ []”?

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(){...}

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

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

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

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

从现在开始已有更好的解决方案。 request默认情况下使用qs来对传入的qs对象进行字符串化,该对象还接受用于格式化它的选项。 此选项之一是arrayFormat ,它接受以下值:

  • indices :默认行为。 产生一个包含索引的字符串: id[0]=foo&id[1]=bar&id[2]=baz 如果您想确保正确的顺序很有用。
  • brackets :产生仅附加brackets的字符串: id[]=foo&id[]=bar&id[]=baz
  • repeat :产生一个不带方括号的字符串: id=foo&id=bar&id=baz 不支持数组的较旧的服务可能会接受此方法,但只会使用最后一个值。

具有此选项的对象将如下所示:

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

另请参见https://github.com/request/request#requestoptions-callback ,其中也提到了该选项。

您想要什么呢? 如果您希望www.test.com?id0=1&id1=3&id2=5 ,则需要为其提供一个params对象,如下所示:

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

如果您已经有一个看起来像{ id: [1,2,3] } ,则需要将该对象转换为上面的对象。 您可以轻松地在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 }

更新:如果您想要一个查询字符串,例如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"

我在for循环中使用了parseInt for因为我假设ID来自不受信任的来源(例如,用户),并且由于您是手动构建字符串而不是使用会为您编码数据的库,所以您想要防止恶意用户向您的请求中注入任意字符串。 您也可以使用encodeURIComponent ,但是如果ID始终为数字,那就太过分了。

我的解决方案是覆盖(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));
}
};

并覆盖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