486 Stimmen

Wie wandelt man URL-Parameter in ein JavaScript-Objekt um?

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
}

471voto

Wolfgang Kuehn Punkte 10819

Im Jahr 2021... Bitte betrachten Sie dies als obsolet.

bearbeiten

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:

  • decodeURI: abc=foo&def=[asf]&xyz=5
  • Anführungszeichen entkommen: gleich, da es keine Anführungszeichen gibt
  • Ersetzen &: abc=foo","def=[asf]","xyz=5
  • Ersetzen =: abc":"foo","def":"[asf]","xyz":"5
  • Umgeben von Locken und Zitaten: {"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"}

Ursprüngliche Antwort

Ein Einzeiler:

JSON.parse('{"' + decodeURI("abc=foo&def=%5Basf%5D&xyz=5".replace(/&/g, "\",\"").replace(/=/g,"\":\"")) + '"}')

404voto

chickens Punkte 14182

One liner. Sauber und einfach.

const params = Object.fromEntries(new URLSearchParams(location.search));

In Ihrem speziellen Fall wäre dies der Fall:

const str = 'abc=foo&def=%5Basf%5D&xyz=5';
const params = Object.fromEntries(new URLSearchParams(str));
console.log(params);

390voto

silicakes Punkte 5788

2022 ES6/7/8 und im Anflug

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;
}

Grundlegende Demo

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"}

Verwendung von Object.fromEntries und Ausbreitung

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

Mehrere gleiche Tasten

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}

87voto

David Hansen Punkte 2481

2022 One-Liner-Ansatz

Für den allgemeinen Fall, dass Sie Abfrageparameter in ein Objekt parsen wollen:

Object.fromEntries(new URLSearchParams(location.search));

Für Ihren speziellen Fall:

Object.fromEntries(new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5'));

35voto

Wayne Punkte 58002

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.com

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.

Powered by:

X