Quiero codificar un objeto json/javascript complejo en la codificación de cadena de consulta estándar. Y quiero decodificar esta cadena de consulta a un objeto json/javascript. Debe ser recursivamente, con arreglos, objetos, cadenas, booleanos y números.
Pensé que esto debería ser fácil, pero se demostró que estaba equivocado. ¿Alguien tiene una idea, cómo resolver este problema? Ya sea en Javascript o preferiblemente en Typescript.
Creo que lo que quieres hacer es codificar y decodificar objetos anidados .
No existe un estándar único, pero muy a menudo se utiliza la sintaxis QS (cadena de consulta):
{ "attribute": "value", "array": ["apples", "bananas"], "object": { "number": 55 }, }se convertirá:
?attribute=value&array[0]=apples&array[1]=bananas&object[number]=55Código de ejemplo:
function decode(querystring: string): object { function parseValue(value: string): any { if (value === 'TRUE') return true; if (value === 'FALSE') return false; return isNaN(Number(value)) ? value : Number(value); } function dec(list: any[], isArray = false): object { let obj: any = isArray ? [] : {}; let recs: any[] = list.filter((item) => { if (item.keys.length > 1) return true; obj[item.keys[0]] = parseValue(item.value); }); let attrs = {}; recs.map((item) => { item.key = item.keys.shift(); attrs[item.key] = []; return item; }).forEach((item) => attrs[item.key].push(item)); Object.keys(attrs).forEach((attr) => { let nextKey = attrs[attr][0].keys[0]; obj[attr] = dec(attrs[attr], typeof nextKey === 'number'); }); return obj; } return dec( querystring .split('&') .map((item) => item.split('=').map((x) => decodeURIComponent(x))) .map((item) => { return { keys: item[0] .split(/[\[\]]/g) .filter((n) => n) .map((key) => (isNaN(Number(key)) ? key : Number(key))), value: item[1], }; }) ); } export function encode(object: object): string { function reducer(obj, parentPrefix = null) { return function (prev, key) { const val = obj[key]; key = encodeURIComponent(key); const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key; if (val == null || typeof val === 'function') { prev.push(`${prefix}=`); return prev; } if (typeof val === 'boolean') { prev.push(`${prefix}=${val.toString().toUpperCase()}`); return prev; } if (['number', 'string'].includes(typeof val)) { prev.push(`${prefix}=${encodeURIComponent(val)}`); return prev; } prev.push( Object.keys(val).reduce(reducer(val, prefix), []).join('&') ); return prev; }; } return Object.keys(object).reduce(reducer(object), []).join('&'); }const obj = { key: 1, key1: 2, key2: 3 } const params = encodeURIComponent(JSON.stringify(obj)) window.location.href = `http://example.com/?query=${params}`terminar así:
http://example.com/?query=%7B%22key%22%3A1%2C%22key1%22%3A2%2C%22key2%22%3A3%7D