Jak mogę uzyskać wartości ciągu zapytania w JavaScript?


2697

Czy istnieje sposób bez wtyczek do pobierania wartości ciągu zapytania za pomocą jQuery (lub bez)?

Jeśli tak to jak? Jeśli nie, czy istnieje wtyczka, która może to zrobić?


Korzystam z wtyczki getUrlParam opisanej w jQuery-Plugin - getUrlParam (wersja 2) .
śpiączka

69
Zwykły javascript rozwiązanie bez RegEx: css-tricks.com/snippets/javascript/get-url-variables
Lorenzo Polidori

6
Chociaż najlepsze rozwiązanie tego pytania zasługuje na popularność ze względu na doskonałą obserwację, że jQuery nie jest potrzebne, jego metoda tworzenia nowych wyrażeń regularnych i ponownego analizowania ciągu zapytania dla każdego pożądanego parametru jest niezwykle nieefektywna. Od dawna istnieją znacznie bardziej wydajne (i wszechstronne) rozwiązania, na przykład w tym artykule przedrukowanym tutaj: htmlgoodies.com/beyond/javascript/article.php/11877_3755006_3/…
Joseph Myers

1
możliwy duplikat ciągu zapytania JavaScript

4
Joseph, „doskonała obserwacja, że ​​jQuery nie jest potrzebny”? Oczywiście to nie jest potrzebne. Wszystko, co robi jQuery, robi przy użyciu JavaScript. Ludzie nie używają jQuery, ponieważ robi rzeczy, których JavaScript nie może zrobić. Celem jQuery jest wygoda.
Vladimir Kornea

Odpowiedzi:


8322

Aktualizacja: wrzesień 2018 r

Możesz użyć URLSearchParams, który jest prosty i ma przyzwoitą (ale nie pełną) obsługę przeglądarki .

const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');

Oryginalny

W tym celu nie potrzebujesz jQuery. Możesz użyć tylko czystego JavaScript:

function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, '\\$&');
    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

Stosowanie:

// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)


Uwaga: Jeśli parametr występuje kilka razy ( ?foo=lorem&foo=ipsum), otrzymasz pierwszą wartość ( lorem). Nie ma w tym standardu, a zastosowania różnią się, patrz na przykład pytanie: Autorytatywna pozycja duplikatów kluczy zapytań HTTP GET .
UWAGA: W funkcji rozróżniana jest wielkość liter. Jeśli wolisz nazwę parametru bez rozróżniania wielkości liter, dodaj modyfikator „i” do RegExp


Jest to aktualizacja oparta na nowych specyfikacjach URLSearchParams, aby bardziej zwięźle osiągnąć ten sam wynik. Zobacz odpowiedź zatytułowaną „ URLSearchParams ” poniżej.


131
Jak ta funkcja obsługuje http://www.mysite.com/index.php?x=x1&x=x2&x=x3Wartość pola xjest niejednoznaczna.
dpp

94
nie obsługuje to także kluczy wielowartościowych , które są również całkowicie legalne.
hurrymaplelad

17
Dlaczego używałbyś do tego wyrażenia regularnego?
Ry-

28
W przypadku kwerendy ?mykey=0&m.+key=1wywołanie getParameterByName("m.+key")wróciłoby 0zamiast 1. namePrzed budowaniem wyrażenia regularnego musisz uciec przed metaznakami wyrażeń regularnych. Wystarczy zadzwonić .replace()tylko raz, używając flagi globalnej i używając "\\$&"wyrażenia zastępującego. Powinieneś szukać location.searchzamiast location.href. Odpowiedź zawierająca ponad 400 głosów pozytywnych powinna uwzględniać te szczegóły.
gilly3

7
Nie potrzebujesz jQuery do tego lub innego celu. Po prostu tego NIE POTRZEBUJESZ.
gztomas

1707

Niektóre zamieszczone tutaj rozwiązania są nieefektywne. Powtarzanie wyszukiwania wyrażeń regularnych za każdym razem, gdy skrypt musi uzyskać dostęp do parametru, jest całkowicie niepotrzebne, wystarczy jedna funkcja do podzielenia parametrów na obiekt w stylu tablicy asocjacyjnej. Jeśli nie pracujesz z interfejsem API historii HTML 5, jest to konieczne tylko raz na ładowanie strony. Inne sugestie również nie mogą poprawnie odkodować adresu URL.

var urlParams;
(window.onpopstate = function () {
    var match,
        pl     = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query  = window.location.search.substring(1);

    urlParams = {};
    while (match = search.exec(query))
       urlParams[decode(match[1])] = decode(match[2]);
})();

Przykład kwerendy:

?i=main&mode=front&sid=de8d49b78a85a322c4155015fdce22c4&enc=+Hello%20&empty

Wynik:

 urlParams = {
    enc: " Hello ",
    i: "main",
    mode: "front",
    sid: "de8d49b78a85a322c4155015fdce22c4",
    empty: ""
}

alert(urlParams["mode"]);
// -> "front"

alert("empty" in urlParams);
// -> true

Można to łatwo poprawić, aby obsługiwać również ciągi zapytań w stylu tablicowym. Przykładem tego jest tutaj , ale ponieważ parametry stylu tablicowego nie są zdefiniowane w RFC 3986, nie będę zanieczyszczać tej odpowiedzi kodem źródłowym. Dla osób zainteresowanych wersją „zanieczyszczoną” zapoznaj się z odpowiedzią Campbeln poniżej .

Ponadto, jak wskazano w komentarzach, ;jest prawnym ogranicznikiem dla key=valuepar. Wymagałoby to bardziej skomplikowanego wyrażenia regularnego do obsługi ;lub &, co moim zdaniem jest niepotrzebne, ponieważ ;jest używane rzadko, a powiedziałbym, że jeszcze bardziej mało prawdopodobne, aby oba były używane. Jeśli potrzebujesz wsparcia ;zamiast &, po prostu zamień je w wyrażeniu regularnym.


Jeśli używasz języka wstępnego przetwarzania po stronie serwera, możesz skorzystać z jego natywnych funkcji JSON, aby wykonać dla ciebie ciężkie podnoszenie. Na przykład w PHP możesz napisać:

<script>var urlParams = <?php echo json_encode($_GET, JSON_HEX_TAG);?>;</script>

O wiele prostsze!

AKTUALIZACJA

Nową funkcją byłoby odzyskiwanie powtarzających się parametrów w następujący sposób myparam=1&myparam=2. Nie ma specyfikacji , jednak większość obecnych podejść opiera się na generowaniu tablicy.

myparam = ["1", "2"]

Oto podejście do zarządzania:

let urlParams = {};
(window.onpopstate = function () {
    let match,
        pl = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) {
            return decodeURIComponent(s.replace(pl, " "));
        },
        query = window.location.search.substring(1);

    while (match = search.exec(query)) {
        if (decode(match[1]) in urlParams) {
            if (!Array.isArray(urlParams[decode(match[1])])) {
                urlParams[decode(match[1])] = [urlParams[decode(match[1])]];
            }
            urlParams[decode(match[1])].push(decode(match[2]));
        } else {
            urlParams[decode(match[1])] = decode(match[2]);
        }
    }
})();

11
jeśli robisz aplikację z dużą mocą ajax, możesz używać skrótu (#), aby „włączyć przycisk Wstecz” ... w takim przypadku kwerenda zmienia się cały czas (zobacz, jak robi to Facebook). .. chociaż te rozwiązania ignorują rzeczy, które pojawiają się po # zawsze ...
Nick Franceschina

100
@Nick: Wszystko po skrócie znajduje się we window.location.hashwłaściwości, która jest oddzielna od window.location.searchwłaściwości. Jeśli skrót zostanie zmieniony, nie wpłynie to w żaden sposób na kwerendę.
Andy E

27
Nie zapominaj, że ;jest to prawny ogranicznik dla key=valuepar GET . Jest to rzadkie, ale wdrożenie zajmuje 5 sekund.
alex

4
Aby być uczciwym, RFC3986 nie określa żadnego konkretnego formatu ciągu zapytania. ?a=b&c=djest konwencjonalny i jest zaleceniem W3C dla formularzy internetowych, ale specyfikacja URI po prostu określa query = *( pchar / "/" / "?" ).
Matthew Gilliard

21
Dla tych z nas, używając dość ścisłą konfigurację JSHint zamienić while(match = search.exec(query))zwhile((match = search.exec(query)) !== null)
craigts

1282

ES2015 (ES6)

getQueryStringParams = query => {
    return query
        ? (/^[?#]/.test(query) ? query.slice(1) : query)
            .split('&')
            .reduce((params, param) => {
                    let [key, value] = param.split('=');
                    params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
                    return params;
                }, {}
            )
        : {}
};

Bez jQuery

var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i)
    {
        var p=a[i].split('=', 2);
        if (p.length == 1)
            b[p[0]] = "";
        else
            b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return b;
})(window.location.search.substr(1).split('&'));

W przypadku adresu URL typu ?topic=123&name=query+stringzwrócony zostanie następujący:

qs["topic"];    // 123
qs["name"];     // query string
qs["nothere"];  // undefined (object)

Metoda Google

Rozdzierając kod Google znalazłem metodę, której używają: getUrlParameters

function (b) {
    var c = typeof b === "undefined";
    if (a !== h && c) return a;
    for (var d = {}, b = b || k[B][vb], e = b[p]("?"), f = b[p]("#"), b = (f === -1 ? b[Ya](e + 1) : [b[Ya](e + 1, f - e - 1), "&", b[Ya](f + 1)][K](""))[z]("&"), e = i.dd ? ia : unescape, f = 0, g = b[w]; f < g; ++f) {
        var l = b[f][p]("=");
        if (l !== -1) {
            var q = b[f][I](0, l),
                l = b[f][I](l + 1),
                l = l[Ca](/\+/g, " ");
            try {
                d[q] = e(l)
            } catch (A) {}
        }
    }
    c && (a = d);
    return d
}

Jest zaciemniony, ale zrozumiały. To nie działa, ponieważ niektóre zmienne są niezdefiniowane.

Zaczynają szukać parametrów w adresie URL od, ?a także od skrótu #. Następnie dla każdego parametru dzielą się na znak równości b[f][p]("=")(który wygląda na to indexOf, że używają pozycji znaku, aby uzyskać klucz / wartość). Po podzieleniu sprawdzają, czy parametr ma wartość, czy nie, a jeśli tak, to przechowują wartość d, w przeciwnym razie po prostu kontynuują.

Ostatecznie obiekt djest zwracany, obsługuje ucieczkę i +znak. Ten obiekt jest podobny do mojego, ma takie samo zachowanie.


Moja metoda jako wtyczki jQuery

(function($) {
    $.QueryString = (function(paramsArray) {
        let params = {};

        for (let i = 0; i < paramsArray.length; ++i)
        {
            let param = paramsArray[i]
                .split('=', 2);

            if (param.length !== 2)
                continue;

            params[param[0]] = decodeURIComponent(param[1].replace(/\+/g, " "));
        }

        return params;
    })(window.location.search.substr(1).split('&'))
})(jQuery);

Stosowanie

//Get a param
$.QueryString.param
//-or-
$.QueryString["param"]
//This outputs something like...
//"val"

//Get all params as object
$.QueryString
//This outputs something like...
//Object { param: "val", param2: "val" }

//Set a param (only in the $.QueryString object, doesn't affect the browser's querystring)
$.QueryString.param = "newvalue"
//This doesn't output anything, it just updates the $.QueryString object

//Convert object into string suitable for url a querystring (Requires jQuery)
$.param($.QueryString)
//This outputs something like...
//"param=newvalue&param2=val"

//Update the url/querystring in the browser's location bar with the $.QueryString object
history.replaceState({}, '', "?" + $.param($.QueryString));
//-or-
history.pushState({}, '', "?" + $.param($.QueryString));

Test wydajności (metoda podziału względem metody wyrażenia regularnego) ( jsPerf )

Kod przygotowania: deklaracja metod

Podziel kod testowy

var qs = window.GetQueryString(query);

var search = qs["q"];
var value = qs["value"];
var undef = qs["undefinedstring"];

Kod testu Regex

var search = window.getParameterByName("q");
var value = window.getParameterByName("value");
var undef = window.getParameterByName("undefinedstring");

Testowanie w przeglądarce Firefox 4.0 x86 w systemie Windows Server 2008 R2 / 7 x64

  • Metoda podziału : 147 780 ± 2,17% najszybciej
  • Metoda Regex : 13 891 ± 0,85% | 90% wolniej

1
Jest to również dobre podejście, dzielenie ciągów zamiast używania wyrażeń regularnych. Jest jednak kilka rzeczy, na które warto zwrócić uwagę :-) 1. unescapejest przestarzałą funkcją i jest zastępowana decodeURIComponent(), należy pamiętać, że żadna z tych funkcji nie rozszyfruje poprawnie +znaku spacji. 2. Powinieneś zadeklarować wynik jako obiekt, a nie tablicę, ponieważ JavaScript sam w sobie nie ma tablic asocjacyjnych, a deklarowana tablica jest traktowana jako obiekt poprzez przypisanie mu nazwanych właściwości.
Andy E,

55
Ciekawe, dlaczego zrobiłbyś to wtyczką jQuery, skoro nie ma żadnego kodu specyficznego dla jQuery?
zachleat

63
@zachleat, jeśli nie masz frameworka, twoje funkcje będą się rozprzestrzeniać po całym kodzie. Jeśli rozszerzysz jQuery, będziesz mieć zakres dla swoich funkcji, nie będzie on pływał gdzieś w twoim kodzie. Myślę, że to jedyny powód.
BrunoLM,

6
Oto wersja jQuery dostosowana do przekazywania JSLint (przynajmniej częściowo poruszający się cel JSLint.com w dniu 15.06.2011). Głównie po prostu przenoszenie rzeczy, aby uspokoić Crockford.
patridge

3
Jak żartował @BenjaminGruenbaum, ja również nie widzę sensu w testowaniu wydajności parsowania adresów URL. Jeśli został on przekształcony w izomorficzny moduł JavaScript, który można wywołać z węzła, powiedzmy, parsować logi, to tak. Ale użycie go do wyodrębnienia parametrów adresu URL window.locationpowoduje, że wszelkie problemy dotyczą wydajności, ponieważ klient nawigujący do adresu URL jest znacznie, znacznie droższy.
Dan Dascalescu,

659

Ulepszona wersja odpowiedzi Artem Barger :

function getParameterByName(name) {
    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

Aby uzyskać więcej informacji na temat ulepszeń, patrz: http://james.padolsey.com/javascript/bujs-1-getparameterbyname/


23
Jeśli chcesz go trochę skrócić, możesz pozbyć się trójkowego warunku i zastąpić go odrobiną zwarcia na ostatniej linii - return match && decodeURIComponent(match[1].replace(/\+/g, ' '));.
Andy E

Zwraca, nulljeśli po parametrze nie występuje „=”. Możesz if (!RegExp('[?&]'+name+'(&.*)?$').exec(window.location.search)) return false;zrobić to, by zwrócił, boolean falsejeśli w ogóle nie ma parametru.
commonpike,

9
Przy newtworzeniu wyrażenia regularnego użyłbym prefiksu:var match = new RegExp('...
Patrick Berkeley,

2
Błąd IE11: IE decyduje się na dodanie poprzedniej wartości znakiem ascii 8206 (hex: 200E - „znak od lewej do prawej”). Zmarnowałem ponad 6 godzin na znalezienie tego! odpowietrzanie terapeutyczne .... naprawić, przyczepić do końca ostatniej linii:.replace('\u200E', '')
JayRO-GreyBeard

W Chrome na Macu przynajmniej (może także w innych przeglądarkach) ostatnią wartością było dołączenie „/”. Zmodyfikowałem więc wyrażenie regularne, aby je zignorować. var results = new RegExp('[\\?&]' + name + '=([^&#/]*)').exec(url);
CaseyB

594

URLSearchParams

Firefox 44+, Opera 36+, Edge 17+, Safari 10.3+ i Chrome 49+ obsługują interfejs API URLSearchParams :

Istnieje sugerowany przez Google polifill URLSearchParams dla stabilnych wersji IE.

Nie jest standaryzowany przez W3C , ale jest standardem życia WhatWG .

Możesz go użyć na location:

let params = new URLSearchParams(location.search);

lub

let params = (new URL(location)).searchParams;

Lub oczywiście pod dowolnym adresem URL:

let url = new URL('https://example.com?foo=1&bar=2');
let params = new URLSearchParams(url.search);

Parametry można również uzyskać, używając .searchParamswłaściwości skróconej obiektu URL, jak poniżej:

let params = new URL('https://example.com?foo=1&bar=2').searchParams;
params.get('foo'); // "1"
params.get('bar'); // "2" 

Czytasz / ustawionych parametrów przez get(KEY), set(KEY, VALUE), append(KEY, VALUE)API. Możesz także iterować wszystkie wartości for (let p of params) {}.

Implementacja referencyjna i strona próbki są dostępne do badania i testowania.


Ci dwaj downvoters prawdopodobnie przeoczyli (tak jak właśnie to zrobiłem) fakt, że musisz użyć .getzamiast po prostu.
Nakilon

20
Tak naprawdę nie musisz go slice(1)włączać .search, możesz go użyć bezpośrednio. URLSearchParams może obsługiwać wiodące ?.
Jason C

URLSearchParamsnie jest dobre, ponieważ nie zwraca rzeczywistych wartości parametrów adresu URL.
Melab

To new URL('https://example.com?foo=1&bar=2') nie działa dla Androida URLfile:///android_asset/...
shah

@Melab jest nadal dobry, ponieważ zapewnia prosty interfejs API dla wszystkich dziwnych wyrażeń regularnych w innych odpowiedziach tutaj. Dziwię się również, że id nie wykonuje domyślnie Window.location.search i że nie ma możliwości zaktualizowania obecnego adresu URL.
Damon

400

Kolejna rekomendacja. Wtyczka Purl umożliwia pobieranie wszystkich części adresu URL, w tym kotwicy, hosta itp.

Można go używać z jQuery lub bez niego.

Użycie jest bardzo proste i fajne:

var url = $.url('http://allmarkedup.com/folder/dir/index.html?item=value'); // jQuery version
var url = purl('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.attr('protocol'); // returns 'http'
url.attr('path'); // returns '/folder/dir/index.html'

Jednak od 11 listopada 2014 Purl nie jest już obsługiwany, a autor zaleca zamiast tego użycie URI.js. Wtyczka jQuery różni się tym, że koncentruje się na elementach - do użytku z ciągami, wystarczy użyć URIbezpośrednio, z lub bez jQuery. Podobny kod wyglądałby jako taki, pełniejsze dokumenty tutaj :

var url = new URI('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.protocol(); // returns 'http'
url.path(); // returns '/folder/dir/index.html'

7
W chwili pisania purl nie jest już utrzymywany, a poprzedni opiekun sugeruje uri.js
Dan Pantry

238

tl; dr

Szybkie, kompletne rozwiązanie , które obsługuje klucze wielowartościowe i zakodowane znaki .

var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {var s = item.split("="), k = s[0], v = s[1] && decodeURIComponent(s[1]); (qd[k] = qd[k] || []).push(v)})

//using ES6   (23 characters cooler)
var qd = {};
if (location.search) location.search.substr(1).split`&`.forEach(item => {let [k,v] = item.split`=`; v = v && decodeURIComponent(v); (qd[k] = qd[k] || []).push(v)})
Wiele podszewek:
var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {
    var s = item.split("="),
        k = s[0],
        v = s[1] && decodeURIComponent(s[1]); //  null-coalescing / short-circuit
    //(k in qd) ? qd[k].push(v) : qd[k] = [v]
    (qd[k] = qd[k] || []).push(v) // null-coalescing / short-circuit
})

Co to za cały ten kod ...
„zerowanie koalescencyjne” , ocena zwarcia
ES6 Zadania destrukcyjne , funkcje strzałek , ciągi szablonów

Przykład:
"?a=1&b=0&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"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

> qd.a[1]    // "5"
> qd["a"][1] // "5"



Przeczytaj więcej ... o rozwiązaniu Vanilla JavaScript.

Aby uzyskać dostęp do różnych części adresu URL, użyj location.(search|hash)

Najłatwiejsze (obojętne) rozwiązanie

var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
  • Obsługuje puste klucze poprawnie.
  • Zastępuje klawisze wielokrotne z ostatnią znalezioną wartością.
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined

Klucze wielowartościowe

Prosta kontrola klucza (item in dict) ? dict.item.push(val) : dict.item = [val]

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {(item.split("=")[0] in qd) ? qd[item.split("=")[0]].push(item.split("=")[1]) : qd[item.split("=")[0]] = [item.split("=")[1]]})
  • Teraz zamiast tego zwraca tablice .
  • Dostęp do wartości przez qd.key[index]lubqd[key][index]
> qd
a: ["1", "5"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined]

Zakodowane postacie?

Użyj decodeURIComponent()do drugiego lub obu podziałów.

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {var k = item.split("=")[0], v = decodeURIComponent(item.split("=")[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v]})
Przykład:
"?a=1&b=0&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"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: ["undefined"]  // decodeURIComponent(undefined) returns "undefined" !!!*
e: ["undefined", "http://w3schools.com/my test.asp?name=ståle&car=saab"]



Z komentarzy

* !!! Uwaga: decodeURIComponent(undefined)zwraca ciąg znaków "undefined". Rozwiązanie polega na prostym użyciu &&, co zapewnia, że decodeURIComponent()nie zostaną wywołane niezdefiniowane wartości. (Zobacz „kompletne rozwiązanie” u góry).

v = v && decodeURIComponent(v);


Jeśli kwerenda jest pusta ( location.search == ""), wynik jest nieco mylący qd == {"": undefined}. Zaleca się sprawdzenie kwerendy przed uruchomieniem funkcji parsowania Like:

if (location.search) location.search.substr(1).split("&").forEach(...)

1
Miły. Jedyne, co chciałbym zmienić - jeśli nie ma więcej niż jednej wartości dla klucza, nie ma potrzeby, aby był to tablica. Używaj tablicy tylko wtedy, gdy na klucz przypada więcej niż jedna wartość.
Pavel Nikolov

2
@PavelNikolov Myślę, że wprowadziłoby to trudności w uzyskaniu czasami tablicy, a czasem wartości. Najpierw musisz to sprawdzić, teraz tylko sprawdzasz długość, bo i tak będziesz używał cykli do pobierania tych wartości. To także miało być najłatwiejsze, ale funkcjonalne rozwiązanie.
Qwerty

@katsh Tak, rzeczywiście działa w> = IE9, jednak możesz nauczyć swój procesor javascript array.forEach()poprzez wstrzyknięcie określonego kodu na początku skryptu. patrz Polyfill developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Qwerty

1
Trochę spłaszczono dla czytelności, przekształcono w funkcję i ponownie użyto split call: function parseQueryString () {var qd = {}; location.search.substr (1) .split ("&"). forEach (function (item) {var parts = item.split ("="); var k = parts [0]; var v = decodeURIComponent (parts [ 1]); (k in qd)? Qd [k] .push (v): qd [k] = [v,]}); zwraca qd; }
Casey

1
decodeDocumentURI (niezdefiniowany) zwraca „niezdefiniowany” zamiast niezdefiniowany. Funkcjonalny ale bardzo elegancki patch: var qd = {}; location.search.substr(1).split("&").forEach( function(item) { var s = item.split("="), k = s[0], v; if(s.length>1) v = decodeURIComponent(s[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v] })
pętla

218

Roshambo na snipplr.com ma prosty skrypt, aby to osiągnąć, opisany w części Uzyskaj parametry adresu URL za pomocą jQuery | Poprawiła . Dzięki jego skryptowi możesz łatwo wyciągnąć tylko te parametry, które chcesz.

Oto sedno:

$.urlParam = function(name, url) {
    if (!url) {
     url = window.location.href;
    }
    var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url);
    if (!results) { 
        return undefined;
    }
    return results[1] || undefined;
}

Następnie po prostu pobierz parametry z ciągu zapytania.

Więc jeśli ciąg adresu URL / zapytania był xyz.com/index.html?lang=de.

Wystarczy zadzwonić var langval = $.urlParam('lang');, a masz to.

UZBEKJON ma również świetny post na blogu, Uzyskaj parametry i wartości URL za pomocą jQuery .


13
jQuery wydaje się oznaczać przestrzeń nazw funkcji do obiektu jQuery. Ponadto, dlaczego jest niepoprawna wartość 0? Jasne, mógłbym zastosować ścisłą kontrolę równości, ale czy nie powinno tak być null?
alex

Zgoda. Działa tak jak normalne odwołanie do zmiennej javascript w ten sposób (z wyjątkiem tego, że zwracanie niezdefiniowanego byłoby bardziej dokładne).
Izochroniczny

„nazwa” nie jest poprawnie usuwana, jest tylko bezpośrednio wstrzykiwana do RegExp. To się nie udaje. Jak powiedzieli inni, to niewiarygodne, że te odpowiedzi zmieniają kierownicę i zdobywają tyle głosów, kiedy należy to zaimplementować w dobrze przetestowanej bibliotece.
Triynko

167

Jeśli używasz jQuery, możesz użyć biblioteki, takiej jak jQuery BBQ: Back Button & Query Library .

... jQuery BBQ zapewnia pełną .deparam()metodę, zarówno zarządzanie stanem skrótu, jak i metody analizy fragmentów / ciągów znaków zapytania i scalania.

Edycja: dodawanie Deparam Przykład:

 var DeparamExample = function() {
            var params = $.deparam.querystring();

            //nameofparam is the name of a param from url
            //code below will get param if ajax refresh with hash
            if (typeof params.nameofparam == 'undefined') {
                params = jQuery.deparam.fragment(window.location.href);
            }
            
            if (typeof params.nameofparam != 'undefined') {
                var paramValue = params.nameofparam.toString();
                  
            }
        };

Jeśli chcesz po prostu używać zwykłego JavaScript, możesz użyć ...

var getParamValue = (function() {
    var params;
    var resetParams = function() {
            var query = window.location.search;
            var regex = /[?&;](.+?)=([^&;]+)/g;
            var match;

            params = {};

            if (query) {
                while (match = regex.exec(query)) {
                    params[match[1]] = decodeURIComponent(match[2]);
                }
            }    
        };

    window.addEventListener
    && window.addEventListener('popstate', resetParams);

    resetParams();

    return function(param) {
        return params.hasOwnProperty(param) ? params[param] : null;
    }

})();​

Ze względu na nowy interfejs API historii HTML, a konkretnie history.pushState()i history.replaceState(), adres URL może się zmienić, co spowoduje unieważnienie pamięci podręcznej parametrów i ich wartości.

Ta wersja będzie aktualizować swoją wewnętrzną pamięć podręczną parametrów przy każdej zmianie historii.


100

Wystarczy użyć dwóch podziałów :

function get(n) {
    var half = location.search.split(n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

Czytałem wszystkie poprzednie i bardziej kompletne odpowiedzi. Ale myślę, że jest to najprostsza i szybsza metoda. Możesz sprawdzić ten test porównawczy jsPerf

Aby rozwiązać problem w komentarzu Rupa, dodaj podział warunkowy, zmieniając pierwszy wiersz na dwa poniżej. Ale absolutna dokładność oznacza, że ​​jest teraz wolniejsza niż regexp (patrz jsPerf ).

function get(n) {
    var half = location.search.split('&' + n + '=')[1];
    if (!half) half = location.search.split('?' + n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

Jeśli więc wiesz, że nie spotkasz się z przeciwną sprawą Rupa, wygrywa. W przeciwnym razie wyreżyseruj.

Lub jeśli masz kontrolę nad kwerendą i możesz zagwarantować, że wartość, którą próbujesz uzyskać, nigdy nie będzie zawierać znaków zakodowanych w adresie URL (posiadanie ich w wartości byłoby złym pomysłem) - możesz użyć następującej, nieco bardziej uproszczonej i czytelnej wersji 1. opcji:

    function getQueryStringValueByName(name) {
        var queryStringFromStartOfValue = location.search.split(name + '=')[1];
         return queryStringFromStartOfValue !== undefined ? queryStringFromStartOfValue.split('&')[0] : null;

7
Bardzo schludny! To nie zadziała, jeśli masz wcześniejszą wartość z nazwą klucza, która kończy się na tej, którą chcesz, np . get('value')Na http://the-url?oldvalue=1&value=2.
Rup

3
Jeśli jednak wiesz, że nazwa parametru oczekuje, będzie to szybsze podejście.
Martin Borthiry,

Edytowane: Jeśli po prostu przetestujesz, że halfjest to prawda, to zwraca wartość null dla pustego parametru, takiego jak ?param=. W takim przypadku powinien zwrócić pusty ciąg znaków, a sprawdzenie to half !== undefinedrozwiązuje.
philh

Fajne! Zrobiłem jeden liniowiec:function get(param){return decodeURIComponent((location.search.split(param+'=')[1]||'').split('&')[0])}
niutech

Musiałem zmienić drugą linię, aby return half !== undefined ? decodeURIComponent(half[1].split('&')[0]) : null;
uruchomić

95

Oto moje zadanie uczynienia z doskonałego rozwiązania Andy'ego E pełnoprawnej wtyczki jQuery:

;(function ($) {
    $.extend({      
        getQueryString: function (name) {           
            function parseParams() {
                var params = {},
                    e,
                    a = /\+/g,  // Regex for replacing addition symbol with a space
                    r = /([^&=]+)=?([^&]*)/g,
                    d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
                    q = window.location.search.substring(1);

                while (e = r.exec(q))
                    params[d(e[1])] = d(e[2]);

                return params;
            }

            if (!this.queryStringParams)
                this.queryStringParams = parseParams(); 

            return this.queryStringParams[name];
        }
    });
})(jQuery);

Składnia jest następująca:

var someVar = $.getQueryString('myParam');

Najlepsze z obu światów!


76

Jeśli wykonujesz więcej manipulacji adresami URL niż po prostu analizując kwerendę, może być pomocne użycie pliku URI.js. Jest to biblioteka do manipulowania adresami URL - i zawiera wszystkie dzwonki i gwizdy. (Przepraszam za autoreklamę tutaj)

aby przekonwertować kwerendę na mapę:

var data = URI('?foo=bar&bar=baz&foo=world').query(true);
data == {
  "foo": ["bar", "world"],
  "bar": "baz"
}

(URI.js także „naprawia” złych querystrings podoba ?&foo&&bar=baz&się ?foo&bar=baz)


// wymagane załadowanie
pliku

1
+1 URI.js to świetna mała wtyczka. Możesz również zrobić var data = URI.parseQuery('?foo=bar&bar=baz&foo=world');dla tego samego wyniku ( dokumenty ).
Yarin

62

Podoba mi się rozwiązanie Ryana Phelana . Ale nie widzę sensu przedłużania jQuery? Nie ma zastosowania funkcji jQuery.

Z drugiej strony podoba mi się wbudowana funkcja w Google Chrome: window.location.getParameter.

Dlaczego więc tego nie użyć? Ok, inne przeglądarki nie mają. Utwórzmy więc tę funkcję, jeśli nie istnieje:

if (!window.location.getParameter ) {
  window.location.getParameter = function(key) {
    function parseParams() {
        var params = {},
            e,
            a = /\+/g,  // Regex for replacing addition symbol with a space
            r = /([^&=]+)=?([^&]*)/g,
            d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
            q = window.location.search.substring(1);

        while (e = r.exec(q))
            params[d(e[1])] = d(e[2]);

        return params;
    }

    if (!this.queryStringParams)
        this.queryStringParams = parseParams(); 

    return this.queryStringParams[key];
  };
}

Ta funkcja jest mniej więcej od Ryana Phelana, ale jest opakowana inaczej: czysta nazwa i brak zależności od innych bibliotek javascript. Więcej o tej funkcji na moim blogu .


3
Wygląda na to, że window.location.getParameter () został usunięty z Chrome.
mhenry1384,

54

Oto szybki sposób na uzyskanie obiektu podobnego do tablicy $ _GET PHP :

function get_query(){
    var url = location.search;
    var qs = url.substring(url.indexOf('?') + 1).split('&');
    for(var i = 0, result = {}; i < qs.length; i++){
        qs[i] = qs[i].split('=');
        result[qs[i][0]] = decodeURIComponent(qs[i][1]);
    }
    return result;
}

Stosowanie:

var $_GET = get_query();

Dla ciągu zapytania x=5&y&z=hello&x=6zwraca obiekt:

{
  x: "6",
  y: undefined,
  z: "hello"
}

jeśli potrzebujesz go jako wtyczki jQuery, oto on: (function($) { $.extend({ get_query: function (name) { var url = location.href; var qs = url.substring(url.indexOf('?') + 1).split('&'); for(var i = 0, result = {}; i < qs.length; i++){ qs[i] = qs[i].split('='); result[qs[i][0]] = qs[i][1]; } return result; } }); })(jQuery);i użyj w ten sposób:$.get_query()
tim 13'13

Dzięki. Skończyło się również na tym. Dodałem to przed twoją instrukcją return: jeśli (param) zwróci wynik [param], w ten sposób mogę również zrobić get_query ('foo') w razie potrzeby
sqram

1
Nie działa, jeśli masz skróty. Na przykład: test.aspx? Test = t1 # default . Zwróci {test: „t1 # default”} i spodziewam się {test: „t1”}
Bogdan M.

@BogdanM: rzeczywiście. location.hrefmusiałby zostać zastąpiony przez location.search.
Dan Dascalescu,

53

Uprość to w prostym kodzie JavaScript:

function qs(key) {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars[key];
}

Zadzwoń z dowolnego miejsca w kodzie JavaScript:

var result = qs('someKey');

1
Myślę, że robisz coś podobnego do mnie, ale myślę, że moje podejście jest DUŻO prostsze stackoverflow.com/a/21152762/985454
Qwerty

Pozwól, że cię przedstawię (bęben proszę) window.location.search!
ErikE

46

To są świetne odpowiedzi, ale potrzebowałem czegoś bardziej solidnego i pomyślałem, że wszyscy chcielibyście mieć to, co stworzyłem.

Jest to prosta metoda biblioteczna, która wykonuje sekcję i manipulowanie parametrami adresów URL. Metoda statyczna ma następujące metody podrzędne, które można wywołać w podanym adresie URL:

  • getHost
  • getPath
  • getHash
  • setHash
  • getParams
  • getQuery
  • setParam
  • getParam
  • hasParam
  • removeParam

Przykład:

URLParser(url).getParam('myparam1')

var url = "http://www.test.com/folder/mypage.html?myparam1=1&myparam2=2#something";

function URLParser(u){
    var path="",query="",hash="",params;
    if(u.indexOf("#") > 0){
        hash = u.substr(u.indexOf("#") + 1);
        u = u.substr(0 , u.indexOf("#"));
    }
    if(u.indexOf("?") > 0){
        path = u.substr(0 , u.indexOf("?"));
        query = u.substr(u.indexOf("?") + 1);
        params= query.split('&');
    }else
        path = u;
    return {
        getHost: function(){
            var hostexp = /\/\/([\w.-]*)/;
            var match = hostexp.exec(path);
            if (match != null && match.length > 1)
                return match[1];
            return "";
        },
        getPath: function(){
            var pathexp = /\/\/[\w.-]*(?:\/([^?]*))/;
            var match = pathexp.exec(path);
            if (match != null && match.length > 1)
                return match[1];
            return "";
        },
        getHash: function(){
            return hash;
        },
        getParams: function(){
            return params
        },
        getQuery: function(){
            return query;
        },
        setHash: function(value){
            if(query.length > 0)
                query = "?" + query;
            if(value.length > 0)
                query = query + "#" + value;
            return path + query;
        },
        setParam: function(name, value){
            if(!params){
                params= new Array();
            }
            params.push(name + '=' + value);
            for (var i = 0; i < params.length; i++) {
                if(query.length > 0)
                    query += "&";
                query += params[i];
            }
            if(query.length > 0)
                query = "?" + query;
            if(hash.length > 0)
                query = query + "#" + hash;
            return path + query;
        },
        getParam: function(name){
            if(params){
                for (var i = 0; i < params.length; i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) == name)
                        return decodeURIComponent(pair[1]);
                }
            }
            console.log('Query variable %s not found', name);
        },
        hasParam: function(name){
            if(params){
                for (var i = 0; i < params.length; i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) == name)
                        return true;
                }
            }
            console.log('Query variable %s not found', name);
        },
        removeParam: function(name){
            query = "";
            if(params){
                var newparams = new Array();
                for (var i = 0;i < params.length;i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) != name)
                          newparams .push(params[i]);
                }
                params = newparams;
                for (var i = 0; i < params.length; i++) {
                    if(query.length > 0)
                        query += "&";
                    query += params[i];
                }
            }
            if(query.length > 0)
                query = "?" + query;
            if(hash.length > 0)
                query = query + "#" + hash;
            return path + query;
        },
    }
}


document.write("Host: " + URLParser(url).getHost() + '<br>');
document.write("Path: " + URLParser(url).getPath() + '<br>');
document.write("Query: " + URLParser(url).getQuery() + '<br>');
document.write("Hash: " + URLParser(url).getHash() + '<br>');
document.write("Params Array: " + URLParser(url).getParams() + '<br>');
document.write("Param: " + URLParser(url).getParam('myparam1') + '<br>');
document.write("Has Param: " + URLParser(url).hasParam('myparam1') + '<br>');

document.write(url + '<br>');

// Remove the first parameter
url = URLParser(url).removeParam('myparam1');
document.write(url + ' - Remove the first parameter<br>');

// Add a third parameter
url = URLParser(url).setParam('myparam3',3);
document.write(url + ' - Add a third parameter<br>');

// Remove the second parameter
url = URLParser(url).removeParam('myparam2');
document.write(url + ' - Remove the second parameter<br>');

// Add a hash
url = URLParser(url).setHash('newhash');
document.write(url + ' - Set Hash<br>');

// Remove the last parameter
url = URLParser(url).removeParam('myparam3');
document.write(url + ' - Remove the last parameter<br>');

// Remove a parameter that doesn't exist
url = URLParser(url).removeParam('myparam3');
document.write(url + ' - Remove a parameter that doesn\"t exist<br>');

44

Z MDN :

function loadPageVar (sVar) {
  return unescape(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + escape(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1"));
}

alert(loadPageVar("name"));

39

Kod golfa:

var a = location.search&&location.search.substr(1).replace(/\+/gi," ").split("&");
for (var i in a) {
    var s = a[i].split("=");
    a[i]  = a[unescape(s[0])] = unescape(s[1]);
}

Pokaż to!

for (i in a) {
    document.write(i + ":" + a[i] + "<br/>");   
};

Na moim komputerze Mac: test.htm?i=can&has=cheezburgerwyświetla się

0:can
1:cheezburger
i:can
has:cheezburger

9
Uwielbiam twoją odpowiedź, zwłaszcza jak zwarty jest skrypt, ale prawdopodobnie powinieneś używać decodeURIComponent. Zobacz xkr.us/articles/javascript/encode-compare and stackoverflow.com/questions/619323/...
pluckyglen,

39

Często używam wyrażeń regularnych, ale nie do tego.

Wydaje mi się łatwiejsze i wydajniejsze odczytanie ciągu zapytania w mojej aplikacji i zbudowanie obiektu ze wszystkich par klucz / wartość, takich jak:

var search = function() {
  var s = window.location.search.substr(1),
    p = s.split(/\&/), l = p.length, kv, r = {};
  if (l === 0) {return false;}
  while (l--) {
    kv = p[l].split(/\=/);
    r[kv[0]] = decodeURIComponent(kv[1] || '') || true;
  }
  return r;
}();

Dla takiego adresu URL http://domain.com?param1=val1&param2=val2możesz uzyskać jego wartość później w kodzie jako search.param1i search.param2.


38
function GET() {
        var data = [];
        for(x = 0; x < arguments.length; ++x)
            data.push(location.href.match(new RegExp("/\?".concat(arguments[x],"=","([^\n&]*)")))[1])
                return data;
    }


example:
data = GET("id","name","foo");
query string : ?id=3&name=jet&foo=b
returns:
    data[0] // 3
    data[1] // jet
    data[2] // b
or
    alert(GET("id")[0]) // return 3

5
To interesujące podejście, zwracające tablicę zawierającą wartości z określonych parametrów. Ma co najmniej jeden problem - niepoprawne dekodowanie wartości przez adres URL, a adres URL musiałby również kodować nazwy parametrów użyte w dopasowaniu. Będzie jednak działał na prostych ciągach zapytań w obecnej formie. ps nie zapomnij użyć słowa kluczowego var podczas deklarowania zmiennych do sprawozdania.
Andy E,

38

Metoda RosQybo jQuery nie zajmowała się dekodowaniem adresu URL

http://snipplr.com/view/26662/get-url-parameters-with-jquery--improved/

Właśnie dodałem tę możliwość również podczas dodawania instrukcji return

return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;

Teraz możesz znaleźć zaktualizowaną treść:

$.urlParam = function(name){
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) { return 0; }
return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;
}

36

Podoba mi się ten (pochodzi z jquery-howto.blogspot.co.uk):

// get an array with all querystring values
// example: var valor = getUrlVars()["valor"];
function getUrlVars() {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

Działa świetnie dla mnie.


36

Oto moja edycja tej doskonałej odpowiedzi - z dodatkową możliwością analizowania ciągów zapytań za pomocą kluczy bez wartości.

var url = 'http://sb.com/reg/step1?param';
var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i) {
        var p=a[i].split('=', 2);
        if (p[1]) p[1] = decodeURIComponent(p[1].replace(/\+/g, " "));
        b[p[0]] = p[1];
    }
    return b;
})((url.split('?'))[1].split('&'));

WAŻNY! Parametr tej funkcji w ostatnim wierszu jest inny. To tylko przykład tego, jak można przekazać do niego dowolny adres URL. Możesz użyć ostatniego wiersza z odpowiedzi Bruno, aby przeanalizować bieżący adres URL.

Co dokładnie się zmieniło? W przypadku adresu URL http://sb.com/reg/step1?param=wyniki będą takie same. Ale z adresem URL http://sb.com/reg/step1?paramrozwiązanie Bruno zwraca obiekt bez kluczy, a mój zwraca obiekt z kluczem parami undefinedwartością.


34

Potrzebowałem obiektu z ciągu zapytania i nie znoszę dużo kodu. Może nie jest to najbardziej niezawodny we wszechświecie, ale to tylko kilka linii kodu.

var q = {};
location.href.split('?')[1].split('&').forEach(function(i){
    q[i.split('=')[0]]=i.split('=')[1];
});

Adres URL typu this.htm?hello=world&foo=barspowoduje utworzenie:

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

4
Schludny. Jednak według Mozilli forEach nie działa na IE7 lub 8 i podejrzewam, że przewróci się, jeśli w ogóle nie będzie ciągu zapytania. Jedno minimalne ulepszenie, które obejmowałoby więcej przypadków, miałoby decodeURIComponentwartość podczas przechowywania - i prawdopodobnie również klucz, ale mniej prawdopodobne jest użycie w tym celu nieparzystych ciągów.
Rup

1
Ładne i proste. Nie obsługuje parametrów tablicy, ?a&b&cale jest to naprawdę bardzo czytelne (a przy okazji podobne do mojego pierwszego pomysłu). Również splitjest zbędny, ale mam większą rybę do smażenia niż dwukrotne podzielenie łańcucha 10 znaków.
cod3monk3y

1
gdy kwerendą jest „? hello = world & one = a = b & two = 2”, to kiedy złapiesz wartość „one”, dostaniesz tylko część przed pierwszym „=” w wartości. jego wartość powinna być „a = b”, ale dostajesz „a”, ponieważ dzielisz „one = a = b” na „=”. to jest po prostu błąd. : ((
Shawn Kovac

2
Chciałbym użyć location.search.substr(1)zamiast, location.href.split('?')[1]aby uniknąć pobierania hash ( #anchor) wraz z ostatnim parametrem zapytania.
mlt

Tak, pozwól, że cię też przedstawię location.search!
ErikE

32

Oto rozszerzona wersja połączonej wersji Andy E. „Obsługuj ciąg zapytania w stylu tablicy”. Naprawiono błąd ( ?key=1&key[]=2&key[]=3; 1został utracony i zastąpiony przez [2,3]), wprowadzono kilka drobnych ulepszeń wydajności (ponowne dekodowanie wartości, ponowne obliczenie pozycji „[” itp.) I dodano szereg ulepszeń (funkcjonalizowany, obsługa ?key=1&key=2, obsługa ;ograniczników) . Zmienne zostawiłem irytująco krótkie, ale dodałem mnóstwo komentarzy, aby były czytelne (och, i ponownie użyłem vfunkcji lokalnych, przepraszam, jeśli jest to mylące;).

Będzie obsługiwał następujące kwerendy ...

? test = Hello & person = neek & person [] = jeff & person [] = jim & person [extra] = John & test3 & nocache = 1398914891264

... przekształcając go w obiekt, który wygląda jak ...

{
    "test": "Hello",
    "person": {
        "0": "neek",
        "1": "jeff",
        "2": "jim",
        "length": 3,
        "extra": "john"
    },
    "test3": "",
    "nocache": "1398914891264"
}

Jak widać powyżej, ta wersja obsługuje pewną miarę tablic „zniekształconych”, tj. - person=neek&person[]=jeff&person[]=jimlub person=neek&person=jeff&person=jimponieważ klucz jest identyfikowalny i ważny (przynajmniej w NameValueCollection.Add dotNet ):

Jeśli określony klucz już istnieje w docelowej instancji NameValueCollection, określona wartość zostanie dodana do istniejącej listy wartości oddzielonych przecinkami w postaci „wartość1, wartość2, wartość3”.

Wygląda na to, że jury ma dość powtarzających się klawiszy, ponieważ nie ma specyfikacji. W takim przypadku wiele kluczy jest przechowywanych jako (fałszywa) tablica. Pamiętaj jednak, że nie przetwarzam wartości na podstawie przecinków w tablice.

Kod:

getQueryStringKey = function(key) {
    return getQueryStringAsObject()[key];
};


getQueryStringAsObject = function() {
    var b, cv, e, k, ma, sk, v, r = {},
        d = function (v) { return decodeURIComponent(v).replace(/\+/g, " "); }, //# d(ecode) the v(alue)
        q = window.location.search.substring(1), //# suggested: q = decodeURIComponent(window.location.search.substring(1)),
        s = /([^&;=]+)=?([^&;]*)/g //# original regex that does not allow for ; as a delimiter:   /([^&=]+)=?([^&]*)/g
    ;

    //# ma(make array) out of the v(alue)
    ma = function(v) {
        //# If the passed v(alue) hasn't been setup as an object
        if (typeof v != "object") {
            //# Grab the cv(current value) then setup the v(alue) as an object
            cv = v;
            v = {};
            v.length = 0;

            //# If there was a cv(current value), .push it into the new v(alue)'s array
            //#     NOTE: This may or may not be 100% logical to do... but it's better than loosing the original value
            if (cv) { Array.prototype.push.call(v, cv); }
        }
        return v;
    };

    //# While we still have key-value e(ntries) from the q(uerystring) via the s(earch regex)...
    while (e = s.exec(q)) { //# while((e = s.exec(q)) !== null) {
        //# Collect the open b(racket) location (if any) then set the d(ecoded) v(alue) from the above split key-value e(ntry) 
        b = e[1].indexOf("[");
        v = d(e[2]);

        //# As long as this is NOT a hash[]-style key-value e(ntry)
        if (b < 0) { //# b == "-1"
            //# d(ecode) the simple k(ey)
            k = d(e[1]);

            //# If the k(ey) already exists
            if (r[k]) {
                //# ma(make array) out of the k(ey) then .push the v(alue) into the k(ey)'s array in the r(eturn value)
                r[k] = ma(r[k]);
                Array.prototype.push.call(r[k], v);
            }
            //# Else this is a new k(ey), so just add the k(ey)/v(alue) into the r(eturn value)
            else {
                r[k] = v;
            }
        }
        //# Else we've got ourselves a hash[]-style key-value e(ntry) 
        else {
            //# Collect the d(ecoded) k(ey) and the d(ecoded) sk(sub-key) based on the b(racket) locations
            k = d(e[1].slice(0, b));
            sk = d(e[1].slice(b + 1, e[1].indexOf("]", b)));

            //# ma(make array) out of the k(ey) 
            r[k] = ma(r[k]);

            //# If we have a sk(sub-key), plug the v(alue) into it
            if (sk) { r[k][sk] = v; }
            //# Else .push the v(alue) into the k(ey)'s array
            else { Array.prototype.push.call(r[k], v); }
        }
    }

    //# Return the r(eturn value)
    return r;
};

Aby uzyskać wartości ciągu zapytania, możesz użyć tej funkcji „GetParameterValues”. W tym musisz tylko podać nazwę parametru stirng zapytania, a zwróci ci wartość $ (dokument) .ready (function () {var bid = GetParameterValues ​​('token');}); funkcja GetParameterValues ​​(param) {var url = decodeURIComponent (window.location.href); url = url.slice (url.indexOf ('?') + 1) .split ('&'); dla (var i = 0; i <url.length; i ++) {var urlparam = url [i] .split ('='); if (urlparam [0] == param) {return urlparam [1]; }}
Mike Clark

1
Używam tego od jakiegoś czasu i jak dotąd było wspaniale. Z wyjątkiem obsługi tablic z kodem url. Korzystanie q = decodeURIComponent(window.location.search.substring(1)),pomaga również to zrobić.
Vladislav Dimitrov

31

Jest to funkcja, którą stworzyłem jakiś czas temu i jestem z niej całkiem zadowolony. Nie rozróżnia wielkości liter - co jest przydatne. Ponadto, jeśli żądany QS nie istnieje, po prostu zwraca pusty ciąg.

Używam skompresowanej wersji tego. Wysyłam nieskompresowane typy początkujących, aby lepiej wyjaśnić, co się dzieje.

Jestem pewien, że można to zoptymalizować lub zrobić inaczej, aby działało szybciej, ale zawsze działało świetnie dla tego, czego potrzebuję.

Cieszyć się.

function getQSP(sName, sURL) {
    var theItmToRtn = "";
    var theSrchStrg = location.search;
    if (sURL) theSrchStrg = sURL;
    var sOrig = theSrchStrg;
    theSrchStrg = theSrchStrg.toUpperCase();
    sName = sName.toUpperCase();
    theSrchStrg = theSrchStrg.replace("?", "&") theSrchStrg = theSrchStrg + "&";
    var theSrchToken = "&" + sName + "=";
    if (theSrchStrg.indexOf(theSrchToken) != -1) {
        var theSrchTokenLth = theSrchToken.length;
        var theSrchTokenLocStart = theSrchStrg.indexOf(theSrchToken) + theSrchTokenLth;
        var theLocOfNextAndSign = theSrchStrg.indexOf("&", theSrchTokenLocStart);
        theItmToRtn = unescape(sOrig.substring(theSrchTokenLocStart, theLocOfNextAndSign));
    }
    return unescape(theItmToRtn);
}

Ponadto lepiej wybrać decodeURI () lub decodeURIComponent () zamiast unescape (). developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Adarsh ​​Konchady

27

Właśnie wypuściliśmy arg.js , projekt mający na celu rozwiązanie tego problemu raz na zawsze. Tradycyjnie było to takie trudne, ale teraz możesz zrobić:

var name = Arg.get("name");

lub uzyskanie całej partii:

var params = Arg.all();

a jeśli zależy Ci na różnicy między, ?query=truea #hash=truenastępnie możesz użyć metod Arg.query()i Arg.hash().


uratowałeś mnie człowieku ... arg.js jest rozwiązaniem żadne z rozwiązań nie otrzymuje wartości z # w IE 8 .. :( każdy szukający IE8 # otrzymuje z żądania to jest rozwiązanie ..
Dilip Rajkumar

27

Problem z najwyższą odpowiedzią na to pytanie polega na tym, że parametry nie są obsługiwane po #, ale czasem trzeba je również uzyskać.

Zmodyfikowałem odpowiedź, aby parsowała pełny ciąg zapytania ze znakiem skrótu również:

var getQueryStringData = function(name) {
    var result = null;
    var regexS = "[\\?&#]" + name + "=([^&#]*)";
    var regex = new RegExp(regexS);
    var results = regex.exec('?' + window.location.href.split('?')[1]);
    if (results != null) {
        result = decodeURIComponent(results[1].replace(/\+/g, " "));
    }
    return result;
};

1
To interesujące, jeśli jej potrzebujesz, ale nie ma standardu dla formatu części mieszającej AFAIK, więc nie jest sprawiedliwe nazywanie tego jako słabość drugiej odpowiedzi.
Rup

2
Tak, wiem. Ale w mojej aplikacji integruję nawigację js innej firmy, która ma pewne parametry po znaku skrótu.
Ph0en1x

Na przykład na stronie wyszukiwania Google po zapytaniu następuje znak krzyżyka „#”.
etlds

25
function GetQueryStringParams(sParam)
{
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');

    for (var i = 0; i < sURLVariables.length; i++)
    {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam)
        {
            return sParameterName[1];
        }
    }
}​

I w ten sposób możesz użyć tej funkcji, zakładając, że jest to adres URL

http://dummy.com/?stringtext=jquery&stringword=jquerybyexample

var tech = GetQueryStringParams('stringtext');
var blog = GetQueryStringParams('stringword');

Jest już kilka implementacji tego podejścia. Przynajmniej musisz zdekodowaćUriComponent () wartości wyników. Może to również źle działać, jeśli nie określisz wartości, np ?stringtext&stringword=foo.
Rup

24

Jeśli używasz Browserify, możesz użyć urlmodułu z Node.js :

var url = require('url');

url.parse('http://example.com/?bob=123', true).query;

// returns { "bob": "123" }

Dalsza lektura: URL Node.js v0.12.2 Podręcznik i dokumentacja

EDYCJA: Możesz użyć interfejsu URL , który jest dość powszechnie przyjęty w prawie wszystkich nowych przeglądarkach, a jeśli kod będzie działał w starej przeglądarce, możesz użyć polifillu takiego jak ten . Oto przykład kodu, w jaki sposób korzystać z interfejsu URL, aby uzyskać parametry zapytania (inaczej parametry wyszukiwania)

const url = new URL('http://example.com/?bob=123');
url.searchParams.get('bob'); 

Możesz również użyć do tego URLSearchParams, oto przykład z MDN, aby to zrobić z URLSearchParams:

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

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

searchParams.has("topic") === true; // true
searchParams.get("topic") === "api"; // true
searchParams.getAll("topic"); // ["api"]
searchParams.get("foo") === null; // true
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic", "More webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString(); // "q=URLUtils.searchParams"

Dokumentacja urlinterfejsu API modułu znajduje się tutaj: nodejs.org/api/url.html
andrezsanchez

Jest to dobre dla rozwoju nw.js. Browserify nie jest nawet potrzebny, ponieważ większość modułów węzłów działa tak, jak w oknie nw.js. Przetestowałem ten kod i działa jak urok bez żadnych modyfikacji.
Andrew Grothe,

OHH to jest niesamowite! URLSearchParams działa idealnie. Wielkie dzięki!
Baran Emre

1
powinien być najlepiej głosowany, bez kłopotów z niestandardowymi funkcjami i dodatkowymi bibliotekami. Wydaje się również, że jest głównie przyjmowany przez przeglądarki 2019.
TheWhiteLlama
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.