是否有一个快速和简单的方法来编码JavaScript对象到字符串,我可以通过GET请求传递?
没有jQuery,没有其他框架-只有纯JavaScript:)
是否有一个快速和简单的方法来编码JavaScript对象到字符串,我可以通过GET请求传递?
没有jQuery,没有其他框架-只有纯JavaScript:)
当前回答
这里有一个简单的答案,在转换过程中同时处理字符串和数组。
jsonToQueryString: function (data) {
return Object.keys(data).map((key) => {
if (Array.isArray(data[key])) {
return (`${encodeURIComponent(key)}=${data[key].map((item) => encodeURIComponent(item)).join('%2C')}`);
}
return(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`);
}).join('&');
}
其他回答
对于TS
const convertQueryToString = (data: { [x: string]: any }): string => { const serialize = (obj: { [x: string]: any }, prefix?: string): string => { const str = []; let p; for (p in obj) { if (obj.hasOwnProperty(p)) { const k = prefix ? `${prefix}[${p}]` : p; const v = obj[p]; str.push( v !== null && typeof v === 'object' ? serialize(v, k) : `${encodeURIComponent(k)}=${encodeURIComponent(v)}` ); } } return str.join('&'); }; return serialize(data); };
对用户187291接受的解决方案的一个小修改:
serialize = function(obj) {
var str = [];
for(var p in obj){
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
}
return str.join("&");
}
检查对象上的hasOwnProperty使JSLint和JSHint高兴,它防止意外序列化对象的方法或其他东西,如果对象不是一个简单的字典。有关JavaScript编程语言的代码约定的语句,请参阅上一段。
const buildSortedQuery = (args) => { 返回种(args) .sort () .map(key => { 返回window.encodeURIComponent(关键) + ' = ' + window.encodeURIComponent (args(例子)); }) . join (' & '); }; console.log (buildSortedQuery ({ Foo:“你好”, 栏:“100%” })); / /酒吧= 100% 25 foo =你好% 20
在讨论了一些最重要的答案之后,我编写了另一个实现,它也可以处理一些边缘情况
function serialize(params, prefix) {
return Object.entries(params).reduce((acc, [key, value]) => {
// remove whitespace from both sides of the key before encoding
key = encodeURIComponent(key.trim());
if (params.constructor === Array ) {
key = `${prefix}[]`;
} else if (params.constructor === Object) {
key = (prefix ? `${prefix}[${key}]` : key);
}
/**
* - undefined and NaN values will be skipped automatically
* - value will be empty string for functions and null
* - nested arrays will be flattened
*/
if (value === null || typeof value === 'function') {
acc.push(`${key}=`);
} else if (typeof value === 'object') {
acc = acc.concat(serialize(value, key));
} else if(['number', 'boolean', 'string'].includes(typeof value) && value === value) { // self-check to avoid NaN
acc.push(`${key}=${encodeURIComponent(value)}`);
}
return acc;
}, []);
}
function objectToQueryString(queryParameters) {
return queryParameters ? serialize(queryParameters).join('&'): '';
}
let x = objectToQueryString({
foo: 'hello world',
bar: {
blah: 123,
list: [1, 2, 3],
'nested array': [[4,5],[6,7]] // will be flattened
},
page: 1,
limit: undefined, // field will be ignored
check: false,
max: NaN, // field will be ignored
prop: null,
' key value': 'with spaces' // space in key will be trimmed out
});
console.log(x); // foo=hello%20world&bar[blah]=123&bar[list][]=1&bar[list][]=2&bar[list][]=3&bar[nested%20array][][]=4&bar[nested%20array][][]=5&bar[nested%20array][][]=6&bar[nested%20array][][]=7&page=1&check=false&prop=&key%20value=with%20spaces
如果您需要发送任意对象,那么GET是一个坏主意,因为有限制的url长度,用户代理和web服务器将接受。我的建议是建立一个名称-值对数组来发送,然后建立一个查询字符串:
function QueryStringBuilder() {
var nameValues = [];
this.add = function(name, value) {
nameValues.push( {name: name, value: value} );
};
this.toQueryString = function() {
var segments = [], nameValue;
for (var i = 0, len = nameValues.length; i < len; i++) {
nameValue = nameValues[i];
segments[i] = encodeURIComponent(nameValue.name) + "=" + encodeURIComponent(nameValue.value);
}
return segments.join("&");
};
}
var qsb = new QueryStringBuilder();
qsb.add("veg", "cabbage");
qsb.add("vegCount", "5");
alert( qsb.toQueryString() );