JavaScript-Abfragezeichenfolge [geschlossen]

106

Gibt es eine JavaScript-Bibliothek, die ein Wörterbuch aus der Abfragezeichenfolge und dem ASP.NETStil erstellt?

Etwas, das verwendet werden kann wie:

var query = window.location.querystring["query"]?

Wird "Abfragezeichenfolge" außerhalb des .NETBereichs als etwas anderes bezeichnet ? Warum wird nicht location.searchin eine Schlüssel- / Wertsammlung aufgeteilt ?

EDIT : Ich habe meine eigene Funktion geschrieben, aber macht das eine große JavaScript-Bibliothek?

Ader
quelle
3
: Diese gefunden medialize.github.com/URI.js
deerchao
1
@davidtaubmann, dass man älter ist, wäre es umgekehrt. Komisch, dass sie im Wesentlichen dasselbe fragen, aber aufgrund des Formats der Frage wurde der Ruhm in den der Community verwandelt und der andere als Off-Topic geschlossen.
Andre Figueiredo

Antworten:

11

Vielleicht http://plugins.jquery.com/query-object/ ?

Dies ist die Gabelung https://github.com/sousk/jquery.parsequery#readme .

Shadow2531
quelle
37
Dies sollte in jquery
gcb
@EvanMulawski Danke. Das Plug-In ist anscheinend einfach verschwunden. Ich habe einen anderen Link hinzugefügt, der helfen könnte.
Shadow2531
Die von CMS bereitgestellte Methode ist einfacher und sauberer. Esp. wenn Sie jquery noch nicht verwenden.
Jcoffland
1
Sie können diese Bibliothek verweisen, um das zu tun - github.com/Mikhus/jsurl
Mikhus
1
Hier ist der richtige Link: plugins.jquery.com/query-object
thexfactor
230

Sie können die Schlüssel / Wert-Paare aus der Eigenschaft location.search extrahieren. Diese Eigenschaft enthält den Teil der URL, der auf das? Symbol, einschließlich der? Symbol.

function getQueryString() {
  var result = {}, queryString = location.search.slice(1),
      re = /([^&=]+)=([^&]*)/g, m;

  while (m = re.exec(queryString)) {
    result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }

  return result;
}

// ...
var myParam = getQueryString()["myParam"];
CMS
quelle
11
Dies ist kein Gewinn. Was ist, wenn der Wert eines Schlüssels das Zeichen '=' enthält? ZB dork.com/?equation=10=2. Man könnte argumentieren, dass es URL-codiert sein sollte, aber es muss sicher nicht sein. Ich habe den Fehler gemacht, selbst einmal eine naive Funktion wie diese zu schreiben. Es gibt mehr als einen Randfall, für den diese Funktion verantwortlich ist.
JamesBrownIsDead
6
@ James, vergessen zu erwähnen, dass ich vor ein paar Monaten die Funktion geändert habe, jetzt kann es richtig mit Ihrem Beispiel umgehen dork.com/?equation=10=2...
CMS
2
@CMS Dies behandelt nicht die Möglichkeit eines Arrays in einer Abfragezeichenfolge, die als solche dargestellt wird. ?val=foo&val=bar&val=baz Wie würden Sie dies berücksichtigen ?
Russ Bradberry
2
@RussBradberry Sie können nicht wirklich haben val=foo&val=bar&val=baz; es müsste seinval[]=foo&val[]=bar&val[]=baz
Brian Driscoll
1
Es schien mir , unvollständig , wenn meine Werte Räume hatte und meine Vars mit gelandet %20ist, so dass ich ersetzt result[keyValuePair[0]] = keyValuePair[1] || '';mitresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601
22

tl; dr Lösung in einer einzelnen (ish) Codezeile unter Verwendung von Vanille-Javascript

var queryDict = {}
location.search.substr(1).split("&").forEach(function(item) {
    queryDict[item.split("=")[0]] = item.split("=")[1]
})

Für die Abfrage ?a=1&b=2&c=3&d&ewird Folgendes zurückgegeben:

> queryDict
a: "1"
b: "2"
c: "3"
d: undefined
e: undefined

mehrwertige Schlüssel und verschlüsselte Zeichen ?

Die ursprüngliche Antwort finden Sie unter Wie kann ich Abfragezeichenfolgenwerte in JavaScript abrufen?

"?a=1&b=2&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> queryDict
a: ["1", "5", "t e x t"]
b: ["2"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]
Qwerty
quelle
8
das ist keine einzelne Zeile - es sind mehrere Zeilen schlecht formatiert!
JonnyRaa
1
Verdammt, ich weiß nicht, was ich sagen soll ... Du hast mich erwischt. Hier haben Sie eine mehrzeilige Lösung: `var queryDict = {}; location.search.substr (1) .split ("&"). forEach (Funktion (Element) {queryDict [item.split ("=") [0]] = item.split ("=") [1]; }); `
Qwerty
2
haha ich liebe es! Es tut mir leid, dass ich mit jemandem zusammengearbeitet habe, der sagte: "Ich habe einen Einzeiler gefunden, der x macht" und Ihnen dann nur 3 Zeilen mit herausgenommenen Zeilenumbrüchen zeigt!
JonnyRaa
@JonnyLeeds Kein Problem, ich weiß genau, was du meinst, aber warum sollte man dann jeden verketteten Befehl in eine neue Zeile schreiben? Dann gibt es eine Funktion als Parameter (Parameter sind normalerweise inline), die nur eine einzige Zuordnung hat. Es schreit, inline zu sein! : D
Qwerty
1
@Qwerty, wahrscheinlich, weil Ihr "Einzeiler" neu formatiert werden sollte, damit das Lesen kein horizontales Scrollen erfordert. Ich habe es angepasst.
P i
8

Nachdem ich diesen Beitrag gefunden hatte, dachte ich, ich sollte hinzufügen, dass ich nicht denke, dass die am besten gewählte Lösung die beste ist. Array-Werte werden nicht verarbeitet (z. B.? A = foo & a = bar - in diesem Fall würde ich erwarten, dass a ['foo', 'bar'] zurückgibt). Soweit ich das beurteilen kann, werden codierte Werte nicht berücksichtigt - z. B. die Hexadezimalcodierung, bei der% 20 ein Leerzeichen darstellt (Beispiel :? A = Hello% 20World) oder das Pluszeichen, das zur Darstellung eines Leerzeichens verwendet wird (Beispiel) :? a = Hallo + Welt).

Node.js bietet eine sehr vollständige Lösung für das Querystring-Parsing. Es wäre einfach, es herauszunehmen und in Ihrem eigenen Projekt zu verwenden, da es ziemlich gut isoliert und unter einer zulässigen Lizenz ist.

Der Code dafür kann hier eingesehen werden: https://github.com/joyent/node/blob/master/lib/querystring.js

Die Tests, die Node hat, können hier eingesehen werden: https://github.com/joyent/node/blob/master/test/simple/test-querystring.js Ich würde vorschlagen, einige davon mit der beliebten Antwort zu versuchen, um zu sehen, wie es geht behandelt sie.

Es gibt auch ein Projekt, an dem ich beteiligt war, um diese Funktionalität speziell hinzuzufügen. Es ist ein Port des Python-Standardmoduls zum Parsen von lib-Abfragezeichenfolgen. Meine Gabel finden Sie hier: https://github.com/d0ugal/jquery.qeeree

d0ugal
quelle
Es gibt nicht nur das Ausleihen des Codes von Node, js, er ist stark miteinander verflochten.
Alfwatt
5

Oder Sie könnten die Bibliothek Sugar.js verwenden .

Von suggerjs.com:

Object.fromQueryString (str , deep = true )

Konvertiert die Abfragezeichenfolge einer URL in ein Objekt. Wenn deep false ist, akzeptiert die Konvertierung nur flache Parameter (dh kein Objekt oder Arrays mit [] -Syntax), da diese nicht allgemein unterstützt werden.

Object.fromQueryString('foo=bar&broken=wear') >{"foo":"bar","broken":"wear"}
Object.fromQueryString('foo[]=1&foo[]=2') >{"foo":[1,2]}

Beispiel:

var queryString = Object.fromQueryString(location.search);
var foo = queryString.foo;
andersh
quelle
3

Wenn Sie den Querystring zur Hand haben, verwenden Sie diesen:

 /**
 * @param qry the querystring
 * @param name name of parameter
 * @returns the parameter specified by name
 * @author [email protected]
 */

function getQueryStringParameter(qry,name){
    if(typeof qry !== undefined && qry !== ""){
        var keyValueArray = qry.split("&");
        for ( var i = 0; i < keyValueArray.length; i++) {
            if(keyValueArray[i].indexOf(name)>-1){
                return keyValueArray[i].split("=")[1];
            }
        }
    }
    return "";
}
Eduardo
quelle
2
// How about this
function queryString(qs) {
    var queryStr = qs.substr(1).split("&"),obj={};
    for(var i=0; i < queryStr.length;i++)
        obj[queryStr[i].split("=")[0]] = queryStr[i].split("=")[1];
    return obj;
}

// Usage:
var result = queryString(location.search);
Ryan C Knaggs
quelle
Dies entspricht mehr oder weniger dem Code "Update: Regex muss nicht verwendet werden" in der Antwort mit der höchsten Bewertung oben. In dieser Frage gibt es auch viele ähnliche Codes . Sie fehlen decodeURIComponentzumindest in den extrahierten Zeichenfolgen.
Rup
@ Rup, das Update wurde nach dieser Antwort gemacht.
Qwerty
@Qwerty Nein, war es nicht: Das Update war im Februar 2013, während diese Antwort fast ein Jahr später im Februar 2014 war. Aber wen interessiert das, es gibt viele ähnliche Codes, die herumfliegen. Meine Kommentare zum decodeURIComponentStand.
Rup
@ Rup Yup, sorry. Und ja.
Qwerty
2

Es ist erwähnenswert, dass die von John Slegers erwähnte Bibliothek eine jQuery-Abhängigkeit aufweist. Hier ist jedoch eine Version, die Vanille-Javascript ist.

https://github.com/EldonMcGuinness/querystring.js

Ich hätte seinen Beitrag einfach kommentiert, aber mir fehlt der Ruf, dies zu tun. : /

Beispiel:

Im folgenden Beispiel wird die folgende, wenn auch unregelmäßige Abfragezeichenfolge verarbeitet:

?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab 

var qs = "?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab";
//var qs = "?=&=";
//var qs = ""

var results = querystring(qs);

(document.getElementById("results")).innerHTML =JSON.stringify(results, null, 2);
<script 
src="https://rawgit.com/EldonMcGuinness/querystring.js/master/dist/querystring.min.js"></script>
<pre id="results">RESULTS: Waiting...</pre>

Eldon McGuinness
quelle
Eigentlich habe ich die jQuery-Abhängigkeit in dem Code entfernt, den ich in meiner Antwort angegeben habe ;-)
John Slegers
2

Der Code

Dieses Gist von Eldon McGuinness ist bei weitem die vollständigste Implementierung eines JavaScript-Abfragezeichenfolgen-Parsers, den ich bisher gesehen habe.

Leider ist es als jQuery-Plugin geschrieben.

Ich habe es in Vanilla JS umgeschrieben und einige Verbesserungen vorgenommen:

function parseQuery(str) {
  var qso = {};
  var qs = (str || document.location.search);
  // Check for an empty querystring
  if (qs == "") {
    return qso;
  }
  // Normalize the querystring
  qs = qs.replace(/(^\?)/, '').replace(/;/g, '&');
  while (qs.indexOf("&&") != -1) {
    qs = qs.replace(/&&/g, '&');
  }
  qs = qs.replace(/([\&]+$)/, '');
  // Break the querystring into parts
  qs = qs.split("&");
  // Build the querystring object
  for (var i = 0; i < qs.length; i++) {
    var qi = qs[i].split("=");
    qi = qi.map(function(n) {
      return decodeURIComponent(n)
    });
    if (typeof qi[1] === "undefined") {
      qi[1] = null;
    }
    if (typeof qso[qi[0]] !== "undefined") {

      // If a key already exists then make this an object
      if (typeof (qso[qi[0]]) == "string") {
        var temp = qso[qi[0]];
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]] = [];
        qso[qi[0]].push(temp);
        qso[qi[0]].push(qi[1]);

      } else if (typeof (qso[qi[0]]) == "object") {
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]].push(qi[1]);
      }
    } else {
      // If no key exists just set it as a string
      if (qi[1] == "") {
        qi[1] = null;
      }
      qso[qi[0]] = qi[1];
    }
  }
  return qso;
}

Wie man es benutzt

var results = parseQuery("?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab");

Ausgabe

{
  "foo": ["bar", "boo" ],
  "roo": "bar",
  "bee": "bop",
  "": ["ghost", "ghost2"],
  "checkbox[]": ["b1", "b2"],
  "dd": null,
  "http": [
    "http://w3schools.com/my test.asp?name=ståle&car=saab",
    "http://w3schools2.com/my test.asp?name=ståle&car=saab"
  ]
}

Siehe auch diese Geige .

John Slegers
quelle
1

function decode(s) {
    try {
        return decodeURIComponent(s).replace(/\r\n|\r|\n/g, "\r\n");
    } catch (e) {
        return "";
    }
}
function getQueryString(win) {
    var qs = win.location.search;
    var multimap = {};
    if (qs.length > 1) {
        qs = qs.substr(1);
        qs.replace(/([^=&]+)=([^&]*)/g, function(match, hfname, hfvalue) {
            var name = decode(hfname);
            var value = decode(hfvalue);
            if (name.length > 0) {
                if (!multimap.hasOwnProperty(name)) {
                    multimap[name] = [];
                }
                multimap[name].push(value);
            }
        });
    }
    return multimap;
}
var keys = getQueryString(window);
for (var i in keys) {
    if (keys.hasOwnProperty(i)) {
        for (var z = 0; z < keys[i].length; ++z) {
            alert(i + ":" + keys[i][z]);
        }
    }
}
Shadow2531
quelle
Sie können den Namen auch .toLowerCase () verwenden, wenn bei der Übereinstimmung des HF-Namens die Groß- und Kleinschreibung nicht berücksichtigt werden soll.
Shadow2531
Sie können auch überprüfen, ob der Wert leer ist oder nicht. Wenn dies der Fall ist, können Sie das Hinzufügen des Eintrags überspringen, sodass das Array nur nicht leere Werte enthält.
Shadow2531
1
unescape () verarbeitet keine UTF-8-Sequenzen, daher möchten Sie möglicherweise decodeURIComponent () verwenden. Wenn Sie jedoch möchten, dass + Zeichen in Leerzeichen dekodiert werden, führen Sie vor dem Dekodieren .replace (/ \ + / g, "") für die Zeichenfolge aus.
Shadow2531
1

Ich mag es einfach, lesbar und klein zu halten.

function searchToObject(search) {
    var pairs = search.substring(1).split("&"),
        obj = {}, pair;

    for (var i in pairs) {
        if (pairs[i] === "") continue;
        pair = pairs[i].split("=");
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }
    return obj;
}

searchToObject(location.search);

Beispiel:

searchToObject('?query=myvalue')['query']; // spits out: 'myvalue'
André Snede Kock
quelle
1

Funktion, die ich für eine ähnliche Anforderung mit reiner Javascript-String-Manipulation geschrieben habe

"http://www.google.lk/?Name=John&Age=20&Gender=Male"

function queryize(sampleurl){
    var tokens = url.split('?')[1].split('&');
    var result = {};

    for(var i=0; i<tokens.length; i++){
        result[tokens[i].split('=')[0]] = tokens[i].split('=')[1];
    }

    return result;
}

Verwendung:

queryize(window.location.href)['Name'] //returns John
queryize(window.location.href)['Age'] //returns 20
queryize(window.location.href)['Gender'] //returns Male
Pranavan Maru
quelle
Ordentlich, aber abgesehen von der Art und Weise, wie Sie die Führung entfernen ?, entspricht dies im Grunde den beiden Antworten über Ihnen?
Rup
Nur eine kleine Verbesserung. Die Art und Weise, wie die Methode verwendet wird, macht es dem Benutzer einfach. Der Benutzer muss nur wissen, welchen Abfragezeichenfolgenwert er benötigt.
Pranavan Maru
1

Wenn Sie lodash + ES6 verwenden, finden Sie hier eine einzeilige Lösung: _.object(window.location.search.replace(/(^\?)/, '').split('&').map(keyVal => keyVal.split('=')));

Ben
quelle
0

Okay, da jeder meine eigentliche Frage ignoriert, werde ich auch meine posten! Folgendes habe ich:

location.querystring = (function() {

    // The return is a collection of key/value pairs

    var queryStringDictionary = {};

    // Gets the query string, starts with '?'

    var querystring = unescape(location.search);

    // document.location.search is empty if no query string

    if (!querystring) {
        return {};
    }

    // Remove the '?' via substring(1)

    querystring = querystring.substring(1);

    // '&' seperates key/value pairs

    var pairs = querystring.split("&");

    // Load the key/values of the return collection

    for (var i = 0; i < pairs.length; i++) {
        var keyValuePair = pairs[i].split("=");
        queryStringDictionary[keyValuePair[0]] = keyValuePair[1];
    }

    // Return the key/value pairs concatenated

    queryStringDictionary.toString = function() {

        if (queryStringDictionary.length == 0) {
            return "";
        }

        var toString = "?";

        for (var key in queryStringDictionary) {
            toString += key + "=" + queryStringDictionary[key];
        }

        return toString;
    };

    // Return the key/value dictionary

    return queryStringDictionary;
})();

Und die Tests:

alert(window.location.querystring.toString());

for (var key in location.querystring) {
    alert(key + "=" + location.querystring[key]);
}

Wohlgemerkt, JavaScript ist nicht meine Muttersprache.

Wie auch immer, ich suche nach einer JavaScript-Bibliothek (zB jQuery, Prototype), in der bereits eine geschrieben ist. :) :)

Ader
quelle
1
Ich bin nicht davon überzeugt, dass Sie wirklich eine Bibliothek benötigen, um drei Codezeilen zu erstellen! Zumindest würden Sie hoffen, dass sich eine Bibliothek an die decodeURIComponent () sowohl an den Schlüssel als auch an den Wert erinnert, was jedes bisher veröffentlichte Code-Snippet nicht geschafft hat.
Bobince
Sie brauchen keine Bibliothek. Ich wollte meine Implementierung mit einer in einer Bibliothek vergleichen, damit ich sehen konnte, ob mir Randfälle fehlten. :)
Kern
Javascript ist nicht Ihre Muttersprache, was es bedeutet, Sie sollten es lernen, auch wenn Sie eine Bibliothek benötigen
Marwan
0

Aufbauend auf der Antwort von @CMS habe ich Folgendes (in CoffeeScript, das leicht in JavaScript konvertiert werden kann):

String::to_query = ->
  [result, re, d] = [{}, /([^&=]+)=([^&]*)/g, decodeURIComponent]
  while match = re.exec(if @.match /^\?/ then @.substring(1) else @)
    result[d(match[1])] = d match[2] 
  result

Sie können ganz einfach greifen, was Sie brauchen:

location.search.to_query()['my_param']

Der Gewinn hier ist eine objektorientierte Schnittstelle (anstatt funktional) und kann für jede Zeichenfolge (nicht nur location.search) ausgeführt werden.

Wenn Sie bereits eine JavaScript-Bibliothek verwenden, ist diese Funktion bereits vorhanden. Hier ist zum Beispiel die Version von Prototype

Eric Anderson
quelle