Die inverse Funktion $ .param () in JavaScript / jQuery

122

Gegeben die folgende Form:

<form>
    <input name="foo" value="bar">
    <input name="hello" value="hello world">
</form>

Ich kann das $.param( .. )Konstrukt verwenden, um das Formular zu serialisieren:

$.param( $('form input') )

=> foo=bar&hello=hello+world

Wie kann ich den obigen String mit JavaScript deserialisieren und einen Hash zurückbekommen?

Beispielsweise,

$.magicFunction("foo=bar&hello=hello+world")

=> {'foo' : 'bar', 'hello' : 'hello world'}

Referenz : jQuery.param( obj ).

seb
quelle
2
Hey, ich füge nur diesen Kommentar hinzu, damit Sie das Update sehen können, das ich am Code vorgenommen habe, falls Sie ihn verwenden ... Ich habe ihn versehentlich so geschrieben, dass er nur den ersten ersetzt +. Jetzt ersetzt es alle!
Blixt
Es werden Plugins aufgerufen QueryString. Ich habe einen erstellt, aber er akzeptiert keine Parameter, sondern liest nur aus window.location.search. Ich erinnere mich an andere, die Parameter akzeptieren ...
BrunoLM
1
überarbeitete jquery BBQ deparam () Methode als NPM-Modul ohne Abhängigkeiten npmjs.com/package/deparam
alexey2baranov
alexey2baranov wie wäre es mit der Umgestaltung von deparam () ohne NPM als Abhängigkeit? :)
Andrew

Antworten:

62

Du solltest benutzen jQuery BBQ ‚s deparam Funktion. Es ist gut getestet und dokumentiert.

cce
quelle
Schönes Plugin! Danke für das Teilen.
Jonathan
29
Wenn Sie nicht das gesamte BBQ-Plugin erhalten möchten, wurde die deparam-Funktion hier als eigenständiges Plugin extrahiert: github.com/chrissrogers/jquery-deparam
Felipe Castro
2
Leider hat die Github-Seite seit Jahren keine Updates mehr gesehen, und als ich sie ausprobiert habe, scheint sie nicht mit der neuesten jQuery kompatibel zu sein ... Sieht aber so aus, wie ich sie brauche.
Pilavdzice
31

Dies ist eine leicht modifizierte Version einer Funktion, die ich vor einiger Zeit geschrieben habe, um etwas Ähnliches zu tun.

var QueryStringToHash = function QueryStringToHash  (query) {
  var query_string = {};
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    pair[0] = decodeURIComponent(pair[0]);
    pair[1] = decodeURIComponent(pair[1]);
        // If first entry with this name
    if (typeof query_string[pair[0]] === "undefined") {
      query_string[pair[0]] = pair[1];
        // If second entry with this name
    } else if (typeof query_string[pair[0]] === "string") {
      var arr = [ query_string[pair[0]], pair[1] ];
      query_string[pair[0]] = arr;
        // If third or later entry with this name
    } else {
      query_string[pair[0]].push(pair[1]);
    }
  } 
  return query_string;
};
QUentin
quelle
1
Genau das, was ich mit der akzeptierten Antwort "Das funktioniert nicht mit Arrays" dachte. Ihre Lösung funktioniert einwandfrei.
Robert Koritnik
20

Wie wäre es mit diesem kurzen funktionalen Ansatz?

function parseParams(str) {
    return str.split('&').reduce(function (params, param) {
        var paramSplit = param.split('=').map(function (value) {
            return decodeURIComponent(value.replace(/\+/g, ' '));
        });
        params[paramSplit[0]] = paramSplit[1];
        return params;
    }, {});
}

Beispiel:

parseParams("this=is&just=an&example") // Object {this: "is", just: "an", example: undefined}
Joel Richard
quelle
1
Dies sollte die akzeptierte Antwort sein, keine externen Abhängigkeiten.
Michael Robinson
Einfache, zuverlässige und leistungsstarke Lösung. Respekt, Sir.
fmquaglia
5
Für das, was es tut, ist es sicherlich eine gute Lösung. Es werden jedoch keine Arrays oder Objekte behandelt, die übergeben werden. Die URL field[][]=a&field[0][]=b&field[0][]=cwird so verarbeitet, wie Object { field[][]: "a", field[0][]: "c" }sie sein sollte resultobject.field[0] = Array [ "a", "b", "c" ]. Dies ist das von PHP erwartete Verhalten. Die Lösung von @ JackyLi kümmert sich darum.
Autos10m
16

Meine Antwort:

function(query){
  var setValue = function(root, path, value){
    if(path.length > 1){
      var dir = path.shift();
      if( typeof root[dir] == 'undefined' ){
        root[dir] = path[0] == '' ? [] : {};
      }

      arguments.callee(root[dir], path, value);
    }else{
      if( root instanceof Array ){
        root.push(value);
      }else{
        root[path] = value;
      }
    }
  };
  var nvp = query.split('&');
  var data = {};
  for( var i = 0 ; i < nvp.length ; i++ ){
    var pair = nvp[i].split('=');
    var name = decodeURIComponent(pair[0]);
    var value = decodeURIComponent(pair[1]);

    var path = name.match(/(^[^\[]+)(\[.*\]$)?/);
    var first = path[1];
    if(path[2]){
      //case of 'array[level1]' || 'array[level1][level2]'
      path = path[2].match(/(?=\[(.*)\]$)/)[1].split('][')
    }else{
      //case of 'name'
      path = [];
    }
    path.unshift(first);

    setValue(data, path, value);
  }
  return data;
}
Jacky Li
quelle
Ja! Ja! Ja! Dies ist genau die, die ich brauche, um die Parameter zu analysieren, die von JQuery in einem $ .ajax-Aufruf gesendet werden. Dies gibt die korrekt verschachtelten Hashes zurück. Vielen Dank, Jacky Li!
Pascal Lindelauf
Die bisher beste Lösung - Es verhält sich ziemlich gut! Aber wenn ich benutze, JSON.stringify(geturlargs('fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc').fld)bekomme ich {"2":["2"],"3":["4"],"":"cc"}und nicht das, [null,null,[2],[3,4],"bb","cc"]was ich mir erhofft hätte (das würde mir PHP geben).
Autos10m
1
Dies ist DIE richtige Antwort und bitte ignorieren Sie alle anderen Antworten, sie funktionieren nicht richtig
Andrew
1
Diese Antwort ist die einzige, die sich mit meinem speziellen Anwendungsfall befasst hat (wenn ich ein Objekt mit verschachtelten Schlüsseln / Werten an jQuerys $ .param übergeben habe, werden diese Werte beim Abrufen ordnungsgemäß hydratisiert).
delinear
9

Ich verwende die Antwort von David Dorward und habe festgestellt, dass es sich nicht wie PHP oder Ruby on Rails verhält, wie sie die Parameter analysieren:

1) Eine Variable ist nur dann ein Array, wenn sie endet [], z. B. ?choice[]=1&choice[]=12nicht, wenn sie endet?a=1&a=2

2) Wenn mehrere Parameter mit demselben Namen vorhanden sind, ersetzen die späteren die früheren wie auf PHP-Servern (Ruby on Rails behält den ersten bei und ignoriert die späteren), z ?a=1&b=2&a=3

Also habe ich Davids Version modifiziert:

function QueryStringToHash(query) {

  if (query == '') return null;

  var hash = {};

  var vars = query.split("&");

  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split("=");
    var k = decodeURIComponent(pair[0]);
    var v = decodeURIComponent(pair[1]);

    // If it is the first entry with this name
    if (typeof hash[k] === "undefined") {

      if (k.substr(k.length-2) != '[]')  // not end with []. cannot use negative index as IE doesn't understand it
        hash[k] = v;
      else
        hash[k.substr(0, k.length-2)] = [v];

    // If subsequent entry with this name and not array
    } else if (typeof hash[k] === "string") {
      hash[k] = v;  // replace it

    // If subsequent entry with this name and is array
    } else {
      hash[k.substr(0, k.length-2)].push(v);
    }
  } 
  return hash;
};

das ist ziemlich gründlich getestet.

Unpolarität
quelle
Die Uri-Spezifikation lautet, dass? A = 1 & a = 2 ein Array sein sollte. Ruby on Rails und PHP folgen nicht der tatsächlichen Spezifikation.
Adiktofsugar
Die Zeile, in der Sie an das Array anhängen, sollte hash[k.substr(0, k.length-2)] = [v];undhash[k.substr(0, k.length-2)].push(v);
Baptiste Pernet
Wäre schön, wenn dies bis npm verfügbar sein könnte
Erik van Velzen
7

Ich weiß, dass dies ein alter Thread ist, aber vielleicht ist er noch relevant?

Inspiriert von Jacky Lis guter Lösung versuchte ich eine kleine Variation meiner eigenen mit dem Ziel, auch beliebige Kombinationen von Arrays und Objekten als Eingabe berücksichtigen zu können. Ich schaute mir an, wie PHP das gemacht hätte und versuchte, etwas "Ähnliches" in Gang zu bringen. Hier ist mein Code:

function getargs(str){
   var ret={};
   function build(urlnam,urlval,obj){ // extend the return object ...
    var i,k,o=obj, x, rx=/\[([^\]]*)\]/g, idx=[urlnam.replace(rx,'')];
    while (x=rx.exec(urlnam)) idx.push(x[1]); 
    while(true){
     k=idx.shift();
     if(k.trim()=='') {// key is empty: autoincremented index
       if (o.constructor.name=='Array') k=o.length; // for Array
       else if (o===obj ) {k=null}  // for first level property name
       else {k=-1;                                  // for Object
         for(i in o) if (+i>k) k=+i;
         k++;
       }
     }
     if(idx.length) { 
       // set up an array if the next key (idx[0]) appears to be
       // numeric or empty, otherwise set up an object:
       if (o[k]==null || typeof o[k]!='object') o[k]=isNaN(idx[0])?{}:[]; 
       o=o[k]; // move on to the next level
     }
     else { // OK, time to store the urlval in its chosen place ...
       // console.log('key',k,'val',urlval);                 
       o[k]=urlval===""?null:urlval; break; // ... and leave the while loop.
     } 
    }
    return obj;
   }
   // ncnvt: is a flag that governs the conversion of
   // numeric strings into numbers
   var ncnvt=true,i,k,p,v,argarr=[],
       ar=(str||window.location.search.substring(1)).split("&"),
       l=ar.length;
   for (i=0;i<l;i++) {if (ar[i]==="") continue;
     p=ar[i].split("=");k=decodeURIComponent(p[0]);
     v=p[1];v=(v!=null)?decodeURIComponent(v.replace(/\+/g,'%20')):'';
     if (ncnvt && v.trim()>"" && !isNaN(v)) v-=0;
     argarr.push([k,v]);  // array: key-value-pairs of all arguments
   }
   for (i=0,l=argarr.length;i<l;i++) build(argarr[i][0],argarr[i][1],ret);
   return ret;
}

Wenn die Funktion ohne das str-argument aufgerufen wird, wird sie window.location.search.slice(1)als Eingabe angenommen.

Einige Beispiele:

['a=1&a=2',                               // 1
 'x[y][0][z][]=1',                        // 2
 'hello=[%22world%22]&world=hello',       // 3
 'a=1&a=2&&b&c=3&d=&=e&',                 // 4
 'fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc',  // 5
 $.param({a:[[1,2],[3,4],{aa:'one',bb:'two'},[5,6]]}), // 6
 'a[]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13',// 7
 'a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13'// 8
].map(function(v){return JSON.stringify(getargs(v));}).join('\n')

führt zu

{"a":2}                                    // 1
{"x":{"y":[{"z":[1]}]}}                    // 2
{"hello":"[\"world\"]","world":"hello"}    // 3
{"a":2,"b":null,"c":3,"d":null,"null":"e"} // 4 = { a: 2, b: null, c: 3, d: null, null: "e" }
{"fld":[null,null,[2],[3,4],"bb","cc"]}    // 5 
{"a":[[1,2],[3,4],{"aa":"one","bb":"two"},[5,6]]}  // 6
{"a":["hi",2,null,[7,99],13]}              // 7
{"a":{"0":2,"3":[7,99],"4":13,"x":"hi"}}   // 8

Während Jacky Lis Lösung den Außenbehälter aals einfaches Objekt produzieren würde

{a:{"0":["1","2"],"1":["3","4"],"2":["5","6"]}} // 6: JackyLi's output

getargs() Betrachtet den ersten angegebenen Index für eine beliebige Ebene, um festzustellen, ob diese Ebene ein Objekt (nicht numerischer Index) oder ein Array (numerisch oder leer) ist, was zu der Ausgabe führt, wie in der obigen Auflistung (Nr. 6) gezeigt.

Wenn das aktuelle Objekt ein Array ist null, wird es an jeder Stelle eingefügt, um leere Positionen darzustellen. Arrays sind immer fortlaufend nummeriert und 0-basiert.

Beachten Sie, dass im Beispiel Nr. 8 Die "automatische Inkrementierung" für leere Indizes funktioniert immer noch, obwohl es sich jetzt um ein Objekt und nicht um ein Array handelt.

Soweit ich es getestet habe, getargs()verhält sich mein Verhalten ziemlich identisch mit dem großartigen jQuery- $.deparam() Plugin von Chriss Roger, das in der akzeptierten Antwort erwähnt wird. Der wesentliche Unterschied besteht darin , dass getargsläuft ohne jQuery und dass es funktioniert Autoincrement in Objekte während $.deparam()wird nicht das tun:

JSON.stringify($.deparam('a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13').a);

führt zu

{"3":["7","99"],"x":"hi","undefined":"13"}

Im $.deparam()Index []wird undefinedanstelle eines automatisch inkrementierten numerischen Index interpretiert .

Autos10m
quelle
Danke für diese tolle Funktion. Ich habe jedoch festgestellt, dass, wenn Sie eine Zahl als Schlüssel im Array verwenden, z. B. '? A [5] [] = x', der Schlüssel beim Erstellen eines Objekts als Zahl verwendet wird und daher in meinem Fall 5 leere Elemente erstellt werden. Es sollte den numerischen Schlüssel als Zeichenfolge behandeln und daher ein Objekt mit "5" (in Anführungszeichen) als Schlüssel und x als Wert erstellen. Ich könnte die URL zwingen, '? A ["5"] [] = x' zu sein, aber das ist hässlich ...
Andrew
@ Andrew: Dies war eine bewusste Designentscheidung von meiner Seite: Soweit ich mich erinnere, wird sich Jacks Lösung mehr so ​​verhalten, wie Sie es erwarten. Ich habe die Zeile o[k]=isNaN(idx[0])?{}:[];mit der Absicht eingeführt, ein Array zu erstellen, wenn ich auf einen numerischen Index stoße, der als erster für ein neues Objekt angegeben wird. Ansonsten mache ich ein generisches Objekt. Es liegt an Ihnen, diesen Teil des Codes so zu ändern, dass er Ihren Anforderungen besser entspricht. I. e. so etwas o[k]={}sollte den Trick machen.
Autos10m
Vielen Dank. PS Sie sollten auf jeden Fall console.log in der Mitte Ihrer Funktion entfernen;)
Andrew
@ Andrew: Danke, habe es gerade auskommentiert. Muss es übersehen haben, als ich den Code gepostet habe.
Autos10m
6

So können Sie eine neue jQuery-Funktion erstellen:

jQuery.unparam = function (value) {
    var
    // Object that holds names => values.
    params = {},
    // Get query string pieces (separated by &)
    pieces = value.split('&'),
    // Temporary variables used in loop.
    pair, i, l;

    // Loop through query string pieces and assign params.
    for (i = 0, l = pieces.length; i < l; i++) {
        pair = pieces[i].split('=', 2);
        // Repeated parameters with the same name are overwritten. Parameters
        // with no value get set to boolean true.
        params[decodeURIComponent(pair[0])] = (pair.length == 2 ?
            decodeURIComponent(pair[1].replace(/\+/g, ' ')) : true);
    }

    return params;
};
Blixt
quelle
4
Ich mag diese Funktion nicht. Warum sollte ein Parameter ohne Wert den Wert 'true' erhalten? Warum nicht null? Ich denke, diese Designentscheidung kann zu sehr subtilen Fehlern führen. Warum nicht auch mit der Situation umgehen, in der Parameter mehrere Werte haben können, anstatt den letzten Wert auszuwählen? Die von David gepostete Lösung ist viel besser.
SolutionYogi
4
Es ist trueso, dass man überprüfen kann if (params.redirect)oder ähnliches. Wenn Sie zwischen trueund anderen Werten unterscheiden möchten , würden Sie verwenden if (params.redirect === true). Ein nullWert würde in keiner Weise helfen, die ich mir vorstellen kann. Der Grund, warum ich es nicht wie David gemacht habe, ist, dass ich Konsistenz über Flexibilität schätze. Mit seiner Methode muss ich überprüfen, ob der Wert ein String oder ein Array ist, um seinen Wert zu verwenden. Meiner Meinung nach sollte es immer eine Zeichenfolge sein (der trueWert wird konvertiert, in 'true'den ich denke, dass er in Ordnung ist) oder immer ein Array. Ich habe String gewählt.
Blixt
Wenn es params.delete wäre, würde es auf true gesetzt und ich werde etwas Schädliches tun. Wie Sie sehen können, ist es einfach, ein Beispiel zu finden. 'null' gibt eindeutig an, dass kein Wert vorhanden ist und die Entscheidung dem Anrufer überlassen bleibt, wie er ihn interpretieren möchte. Betrachten Sie mehrere Werte so. Indem Sie aufessen, stellen Sie sicher, dass jeder Anrufer Zeit damit verbringt, zu debuggen, warum er nur einen Wert erhält, ODER später kommt und den Code ändert. Durch die Rückgabe des Arrays im Voraus weiß der Anrufer sofort, wie er damit umgehen soll. Das Verwerfen von Informationen ist meiner Meinung nach niemals gut.
SolutionYogi
2
Wenn die URL /abc?deletedann ist, würde ich erwarten, dass es einen Eintrag für gibt delete. Ich sehe nicht, wie das anders ist? Ich sehe nicht einmal, wie Sie den anderen Code aus diesem Grund bevorzugen können, da dieser Code den Wert auf die Zeichenfolge setzt, 'undefined'die nicht besser ist. Bei mehreren Werten geht es um Einfachheit und Flexibilität. Ich sehe selten die Verwendung mehrerer Werte in Abfragezeichenfolgen, aber wenn Sie sie möchten, geben Sie immer ein Array mit 1+ Werten zurück. Mischen Sie niemals den Rückgabetyp. dann Sie werden Zeit haben , um Debug zu verbringen , weil , was in der Regel eine Zeichenfolge plötzlich ein Array sein könnte.
Blixt
Vielen Dank. Ich glaube nicht, dass es eine Silberkugel gibt. Ich habe Ihren Code genommen und ein wenig geändert, die booleschen Werte entfernt und das Parsen von Array-Parametern hinzugefügt. foo [] = 1 & foo [] = 2 => foo: ["1", "2"]
16.
6

Dank ihm http://james.padolsey.com/javascript/parsing-urls-with-the-dom/

Ziemlich einfach: D.

function params_unserialize(p){
var ret = {},
    seg = p.replace(/^\?/,'').split('&'),
    len = seg.length, i = 0, s;
for (;i<len;i++) {
    if (!seg[i]) { continue; }
    s = seg[i].split('=');
    ret[s[0]] = s[1];
}
return ret;}
brutuscat
quelle
2
Dies funktioniert nicht mit Auswahlfeldern mit mehreren Optionen, da nur die zuletzt ausgewählten Felder beibehalten werden.
Fernando Fabreti
Entschuldigung, aber ich kann nicht sehen, worauf Sie sich im Kommentar beziehen. Die Funktion, auf die hier verwiesen wird, besteht darin, einen URI mit Parametern wie ?something=1&param2=value2in einem Array zu unserialisieren / zu analysieren . Was meinst du mit "nicht mit Auswahlfeldern mit mehreren Optionen arbeiten"?
Brutuscat
4

Hier ist meine JavaScript-Implementierung, die ich in einer serverseitigen JScript ASP Classic- Seite ( Demo ) verwende:

// Transforms a query string in the form x[y][0][z][]=1 into {x:{y:[{z:[1]}]}}
function parseJQueryParams(p) {
    var params = {};
    var pairs = p.split('&');
    for (var i=0; i<pairs.length; i++) {
        var pair = pairs[i].split('=');
        var indices = [];
        var name = decodeURIComponent(pair[0]),
            value = decodeURIComponent(pair[1]);

        var name = name.replace(/\[([^\]]*)\]/g, 
            function(k, idx) { indices.push(idx); return ""; });

        indices.unshift(name);
        var o = params;

        for (var j=0; j<indices.length-1; j++) {
            var idx = indices[j];
            var nextIdx = indices[j+1];
            if (!o[idx]) {
                if ((nextIdx == "") || (/^[0-9]+$/.test(nextIdx)))
                    o[idx] = [];
                else
                    o[idx] = {};
            }
            o = o[idx];
        }

        idx = indices[indices.length-1];
        if (idx == "") {
            o.push(value);
        }
        else {
            o[idx] = value;
        }
    }
    return params;
}
Yuval
quelle
Bisher das Beste, was ich für verschachtelte Arrays gefunden habe
ymakux
3

benutze das :

// convert query string to json object
var queryString = "cat=3&sort=1&page=1";

queryString
    .split("&")
    .forEach((item) => {
        const prop = item.split("=");
        filter[prop[0]] = prop[1];
    });

console.log(queryString);
Mohmmad Ebrahimi Aval
quelle
1

Ich habe mir diese Lösung ausgedacht, die sich wie die .Net-Funktion verhält HttpUtility.ParseQueryString .

Im Ergebnis werden die Abfragezeichenfolgenparameter in Eigenschaften als Wertelisten gespeichert, sodass qsObj["param"]dies mit dem Aufruf identisch istGetValues("param") von .Net entspricht.

Ich hoffe du magst es. JQuery nicht erforderlich.

var parseQueryString = function (querystring) {
    var qsObj = new Object();
    if (querystring) {
        var parts = querystring.replace(/\?/, "").split("&");
        var up = function (k, v) {
            var a = qsObj[k];
            if (typeof a == "undefined") {
                qsObj[k] = [v];
            }
            else if (a instanceof Array) {
                a.push(v);
            }
        };
        for (var i in parts) {
            var part = parts[i];
            var kv = part.split('=');
            if (kv.length == 1) {
                var v = decodeURIComponent(kv[0] || "");
                up(null, v);
            }
            else if (kv.length > 1) {
                var k = decodeURIComponent(kv[0] || "");
                var v = decodeURIComponent(kv[1] || "");
                up(k, v);
            }
        }
    }
    return qsObj;
};

So verwenden Sie es:

var qsObj = parseQueryString("a=1&a=2&&b&c=3&d=&=e&");

Um eine Vorschau des Ergebnisses in der Konsole anzuzeigen, geben Sie Folgendes ein:

JSON.stringify(qsObj)

Ausgabe:

"{"a":["1","2"],"null":["","b",""],"c":["3"],"d":[""],"":["e"]}"

quelle
1

Bei CSS-Tricks gibt es einen wunderschönen Einzeiler (Originalquelle von Nicholas Ortenzio ):

function getQueryParameters(str) {
    return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
}

Der wirklich clevere Teil ist, wie das thisObjekt der anonymen Funktion verwendet wird und für jede der Abfragen in der Zeichenfolge ein Schlüssel / Wert-Paar hinzugefügt wird. Trotzdem gibt es Raum für Verbesserungen. Ich habe es unten ein wenig geändert, mit den folgenden Änderungen:

  1. Behandlung von leeren Zeichenfolgen und Eingaben ohne Zeichenfolge hinzugefügt.

  2. Behandelte URI-codierte Zeichenfolgen ( %40-> @usw.).

  3. Die Standardverwendung von " document.location.searchWenn die Eingabe leer war" wurde entfernt.

  4. Der Name wurde geändert, lesbarer gemacht und Kommentare hinzugefügt.

function deparam(str) {
    // Uses an empty 'this' to build up the results internally
    function splitQuery(query) {
        query = query.split('=').map(decodeURIComponent);
        this[query[0]] = query[1];
        return this;
    }

    // Catch bad input
    if (!str || !(typeof str === 'string' || str instanceof String))
        return {};

    // Split the string, run splitQuery on each piece, and return 'this'
    var queries = str.replace(/(^\?)/,'').split('&');
    return queries.map(splitQuery.bind({}))[0];
}
Erik Koopmans
quelle
1

Dies ist eine wirklich alte Frage, aber da ich gekommen bin, kommen möglicherweise andere Leute zu diesem Beitrag, und ich möchte dieses Thema ein wenig auffrischen. Heute müssen keine benutzerdefinierten Lösungen mehr erstellt werden - es gibt eine URLSearchParams- Oberfläche.

var paramsString = "q=URLUtils.searchParams&topic=api";
var searchParams = new URLSearchParams(paramsString);

//Iterate the search parameters.
for (let p of searchParams) {
  console.log(p);
}

Die einzige Einschränkung, die ich kenne - diese Funktion wird in IE / Edge nicht unterstützt.

Igor Benikov
quelle
Leider nicht wie gewohnt vom IE unterstützt, falls Sie diesen Browser unterstützen müssen.
Lauren
0

Dies ist meine Version in Coffeescript. Funktioniert auch für URL wie http://localhost:4567/index.html?hello=[%22world%22]&world=hello#/home

getQueryString: (url)->
    return null if typeof url isnt 'string' or url.indexOf("http") is -1

    split = url.split "?"

    return null if split.length < 2 
    path = split[1]

    hash_pos = path.indexOf "#"
    path = path[0...hash_pos] if hash_pos isnt -1

    data = path.split "&"
    ret = {}
    for d in data
      [name, val] = d.split "=" 
      name = decodeURIComponent name
      val = decodeURIComponent val
      try 
        ret[name] = JSON.parse val
      catch error
        ret[name] = val
    return ret
coderek
quelle
0

Hier ist eine einfache und kompakte Version, wenn Sie die Parameter nur schnell aus einer GET-Anforderung abrufen möchten:

function httpGet() {
    var a={},b,i,q=location.search.replace(/^\?/,"").split(/\&/);
    for(i in q) if(q[i]) {b=q[i].split("=");if(b[0]) a[b[0]]=
    decodeURIComponent(b[1]).replace(/\+/g," ");} return a;
}

Es konvertiert

something?aa=1&bb=2&cc=3

in ein Objekt wie

{aa:1,bb:2,cc:3}
dkellner
quelle
0

Erstellt eine serialisierte Darstellung eines Arrays oder Objekts (kann als URL-Abfragezeichenfolge für AJAX-Anforderungen verwendet werden).

<button id='param'>GET</button> 
<div id="show"></div>
<script>
  $('#param').click(function () {
    var personObj = new Object();
    personObj.firstname = "vishal"
    personObj.lastname = "pambhar";
    document.getElementById('show').innerHTML=$.param(`personObj`));
  });
</script>
output:firstname=vishal&lastname=pambhar
Vishal Patel
quelle
1
Code ohne Erklärungen ist nicht willkommen. Könnten Sie bitte Ihren Code erklären?
L. Guthardt
Erstellt eine serialisierte Darstellung eines Arrays oder Objekts (kann als URL-
Vishal Patel
Bitte fügen Sie Erklärungen direkt in Ihre Antwort ein, indem Sie sie bearbeiten. Nicht in Kommentaren.
L. Guthardt
-1

Antworten könnten etwas jQuery- Eleganz gebrauchen :

(function($) {
var re = /([^&=]+)=?([^&]*)/g;
var decodeRE = /\+/g; // Regex for replacing addition symbol with a space
var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );};
$.parseParams = function(query) {
    var params = {}, e;
    while ( e = re.exec(query) ) {
        var k = decode( e[1] ), v = decode( e[2] );
        if (k.substring(k.length - 2) === '[]') {
            k = k.substring(0, k.length - 2);
            (params[k] || (params[k] = [])).push(v);
        }
        else params[k] = v;
    }
    return params;
};
})(jQuery);

Gabelung unter https://gist.github.com/956897

kares
quelle
-1

Sie können die Funktion .serializeArray()( Link ) von jQuery selbst verwenden. Diese Funktion gibt ein Array von Schlüssel-Wert-Paaren zurück. Ergebnisbeispiel:

[
  { name: "id", value: "1" },
  { name: "version", value: "100" }
]
Jefferson Henrique C. Soares
quelle
1
Dies wurde nicht gefragt. Er möchte eine Schnur in einen Hash verwandeln. serializeArray nimmt eine Form an und gibt ein Array zurück.
Daniel Bang