[英]Alexa Skill Development, Fetching JSON Data from URL with 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.