Ich habe einen String wie diesen:
abc=foo&def=%5Basf%5D&xyz=5
Wie kann ich sie in ein JavaScript-Objekt wie dieses umwandeln?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
Ich habe einen String wie diesen:
abc=foo&def=%5Basf%5D&xyz=5
Wie kann ich sie in ein JavaScript-Objekt wie dieses umwandeln?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
Diese Bearbeitung verbessert und erklärt die Antwort auf der Grundlage der Kommentare.
var search = location.search.substring(1);
JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')
Ejemplo
Parsen abc=foo&def=%5Basf%5D&xyz=5
in fünf Schritten:
abc=foo","def=[asf]","xyz=5
abc":"foo","def":"[asf]","xyz":"5
{"abc":"foo","def":"[asf]","xyz":"5"}
was legal JSON ist.
Eine verbesserte Lösung erlaubt mehr Zeichen im Suchstring. Es verwendet eine Reviver-Funktion für die URI-Dekodierung:
var search = location.search.substring(1);
JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) })
Ejemplo
search = "abc=foo&def=%5Basf%5D&xyz=5&foo=b%3Dar";
gibt
Object {abc: "foo", def: "[asf]", xyz: "5", foo: "b=ar"}
Ein Einzeiler:
JSON.parse('{"' + decodeURI("abc=foo&def=%5Basf%5D&xyz=5".replace(/&/g, "\",\"").replace(/=/g,"\":\"")) + '"}')
Ab ES6 bietet Javascript mehrere Konstrukte, um eine performante Lösung für dieses Problem zu schaffen.
Dazu gehört die Verwendung von URLSearchParams y Iteratoren
let params = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
params.get("abc"); // "foo"
Sollte Ihr Anwendungsfall erfordern, dass Sie es tatsächlich in ein Objekt umwandeln, können Sie die folgende Funktion implementieren:
function paramsToObject(entries) {
const result = {}
for(const [key, value] of entries) { // each 'entry' is a [key, value] tupple
result[key] = value;
}
return result;
}
const urlParams = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
const entries = urlParams.entries(); //returns an iterator of decoded [key,value] tuples
const params = paramsToObject(entries); //{abc:"foo",def:"[asf]",xyz:"5"}
Wir können verwenden Object.fromEntries und ersetzt paramsToObject
mit Object.fromEntries(entries)
.
Die Wertepaare, über die iteriert werden soll, sind die Liste Name-Wert-Paare mit dem Schlüssel ist der Name und der Wert ist der Wert.
Seit URLParams
gibt ein iterierbar Objekt, unter Verwendung der Spread-Operator statt des Aufrufs .entries
wird ebenfalls Einträge gemäß seiner Spezifikation liefern:
const urlParams = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
const params = Object.fromEntries(urlParams); // {abc: "foo", def: "[asf]", xyz: "5"}
Nota: Alle Werte sind automatisch Zeichenketten gemäß der URLSearchParams-Spezifikation
Als @siipe darauf hingewiesen, werden Zeichenketten, die mehrere Werte mit gleichem Schlüssel enthalten, in den letzten verfügbaren Wert umgewandelt: foo=first_value&foo=second_value
wird im Wesentlichen werden: {foo: "second_value"}
.
Wie in dieser Antwort: https://stackoverflow.com/a/1746566/1194694 Es gibt keine Spezifikation für die Entscheidung, was damit zu tun ist, und jeder Rahmen kann sich anders verhalten.
Ein üblicher Anwendungsfall ist die Verknüpfung von zwei gleichen Werten in einem Array, wodurch das Ausgabeobjekt zu wird:
{foo: ["first_value", "second_value"]}
Dies kann mit folgendem Code erreicht werden:
const groupParamsByKey = (params) => [...params.entries()].reduce((acc, tuple) => {
// getting the key and value from each tuple
const [key, val] = tuple;
if(acc.hasOwnProperty(key)) {
// if the current key is already an array, we'll add the value to it
if(Array.isArray(acc[key])) {
acc[key] = [...acc[key], val]
} else {
// if it's not an array, but contains a value, we'll convert it into an array
// and add the current value to it
acc[key] = [acc[key], val];
}
} else {
// plain assignment if no special case is present
acc[key] = val;
}
return acc;
}, {});
const params = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5&def=dude');
const output = groupParamsByKey(params) // {abc: "foo", def: ["[asf]", "dude"], xyz: 5}
Aufteilen auf &
um Name/Wert-Paare zu erhalten, dann jedes Paar aufteilen =
. Hier ist ein Beispiel:
var str = "abc=foo&def=%5Basf%5D&xy%5Bz=5"
var obj = str.split("&").reduce(function(prev, curr, i, arr) {
var p = curr.split("=");
prev[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
return prev;
}, {});
Ein anderer Ansatz ist die Verwendung regulärer Ausdrücke:
var obj = {};
str.replace(/([^=&]+)=([^&]*)/g, function(m, key, value) {
obj[decodeURIComponent(key)] = decodeURIComponent(value);
});
Dies ist eine Adaption von John Resigs "Suchen und nicht Ersetzen" .
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.