Uzyskaj wartości adresu URL parametrów ciągu zapytania za pomocą jQuery / Javascript (querystring)

149

Czy ktoś zna dobry sposób na napisanie rozszerzenia jQuery do obsługi parametrów ciągu zapytania? Zasadniczo chcę rozszerzyć magiczną ($)funkcję jQuery, aby móc zrobić coś takiego:

$('?search').val(); 

Co dałoby mi „test” wartość w następującym adresem: http://www.example.com/index.php?search=test.

Widziałem wiele funkcji, które potrafią to zrobić w jQuery i Javascript, ale tak naprawdę chcę rozszerzyć jQuery, aby działało dokładnie tak, jak pokazano powyżej. Nie szukam wtyczki jQuery, szukam rozszerzenia do metody jQuery.

TroySteven
źródło
4
Zapytany i odpowiedział: stackoverflow.com/questions/901115/…
Nico Westerdale
1
@NicoWesterdale - przeszedłem przez ten link, ale nie widziałem żadnych odpowiedzi, które rozwiązałyby to konkretne pytanie. Powiedział, że chce dokładnie tak, jak powyżej.
mrtsherman,
2
Myślę, że nie możesz tego zrobić, przekazany łańcuch jest analizowany przez program sizzler, a następnie tłumaczony na tablicę obiektów DOM. Możesz rozszerzyć dopasowanie, aby zapewnić niestandardowe filtry, ale nie możesz mieć obiektu jquery opartego na łańcuchu.
Andrew,
6
Czy nie jest $wystarczająco przeciążony?
Quentin,
1
@mrtsherman Spójrz na funkcję getParameterByName () w linku, który podałem. Nie, nie możesz tego zrobić bezpośrednio w znaku zachęty $, ale nie do tego służą selektory jQuery. Po prostu wybiera część ciągu adresu URL, a nie próbuje uzyskać dostępu do części DOM, co robi $ (). To zupełnie inna sprawa. Jeśli naprawdę chciałbyś używać jQuery, możesz napisać wtyczkę, która używałaby takiej składni: $ .getParameterByName (param), jest przykład poniżej na tej stronie, do której linkowałem, który robi dokładnie to. Jednak trochę bezcelowe.
Nico Westerdale

Odpowiedzi:

46

Po latach brzydkiego analizowania ciągów znaków jest lepszy sposób: URLSearchParams Przyjrzyjmy się, jak możemy użyć tego nowego interfejsu API do pobierania wartości z lokalizacji!

// Zakładając "? Post = 1234 & action = edit"

var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?

post=1234&action=edit&active=1"

UPDATE: IE nie jest obsługiwany

użyj tej funkcji z odpowiedzi poniżej zamiast URLSearchParams

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('action')); //edit
Saurin
źródło
1
czy URLSearchParams jest obsługiwany przez wszystkie przeglądarki?
boski
Ups! O rany, IE nie jest obsługiwane !! Właśnie to przetestowałem. Podczas gdy Chrome, FF, Safari nie ma problemu.
Saurin,
1
@divine - Tutaj znajduje się polyfill dla URLSearchParams: github.com/WebReflection/url-search-params
Roberto
Jeśli dodasz polyfill dla nieobsługiwanych przeglądarek, to rozwiązanie URLSearchParams działa dobrze. github.com/ungap/url-search-params
Louisvdw
104

Po co rozszerzać jQuery? Jaka byłaby korzyść z rozszerzenia jQuery w porównaniu z posiadaniem funkcji globalnej?

function qs(key) {
    key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars
    var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
    return match && decodeURIComponent(match[1].replace(/\+/g, " "));
}

http://jsfiddle.net/gilly3/sgxcL/

Alternatywnym podejściem byłoby przeanalizowanie całego ciągu zapytania i zapisanie wartości w obiekcie do późniejszego wykorzystania. To podejście nie wymaga wyrażenia regularnego i rozszerza window.locationobiekt (ale równie łatwo można by użyć zmiennej globalnej):

location.queryString = {};
location.search.substr(1).split("&").forEach(function (pair) {
    if (pair === "") return;
    var parts = pair.split("=");
    location.queryString[parts[0]] = parts[1] &&
        decodeURIComponent(parts[1].replace(/\+/g, " "));
});

http://jsfiddle.net/gilly3/YnCeu/

Ta wersja korzysta również z Array.forEach(), która jest natywnie niedostępna w IE7 i IE8. Można go dodać za pomocą implementacji w MDN lub $.each()zamiast tego można użyć jQuery .

gilly3
źródło
2
Nie jest to powszechne, ale w parametrach zapytania można używać średników zamiast ampersandów.
Muhd,
@Muhd - „Prawidłowe” jest użycie dowolnego separatora, który lubisz w zapytaniu, o ile Twój kod go rozumie. Jednak po przesłaniu formularza pola formularza są przesyłane jako name=valuepary, oddzielone znakiem &. Jeśli twój kod używa niestandardowego formatu kwerend, oczywiście, będziesz musiał napisać niestandardowy parser kwerendy wszędzie tam, gdzie kwerenda jest używana, czy to na serwerze, czy na kliencie.
gilly3
2
@nick - ciekawe. Jednak ich sugestia, aby serwery HTTP traktowały średniki jako ampersandy tylko po to, by uczynić HTML ładniejszym, gdy używa się linku do naśladowania przesłania formularza. To tylko sugestia i jest niestandardowy. Standardowe przesłanie formularza GETjest kodowane jako application/x-www-form-urlencoded, z wartościami oddzielonymi &. Mój kod obsługuje ten standard. Niestandardowe struktury adresów URL, takie jak ta, którą łączysz, będą wymagały niestandardowego parsera po stronie serwera i klienta. Niezależnie od tego, dodanie takiej możliwości do mojego kodu powyżej byłoby trywialne.
gilly3
1
@gilly rzeczywiście - jeśli chcesz mieć przenośny kod, musisz obsługiwać oba
nick
1
Dodaj „i” do RegExp (), aby klucz nie rozróżniał wielkości liter: new RegExp ("[? &]" + Key + "= ([^ &] +) (& | $)", "i"));
Yovav,
94

Wtyczka JQuery jQuery-URL-Parser wykonuje to samo zadanie, na przykład w celu pobrania wartości parametru ciągu zapytania wyszukiwania , możesz użyć

$.url().param('search');

Ta biblioteka nie jest aktywnie zarządzana. Jak sugeruje autor tej samej wtyczki, można użyć URI.js .

Możesz też zamiast tego użyć js-url . Jest dość podobny do tego poniżej.

Możesz więc uzyskać dostęp do parametrów zapytania, takich jak $.url('?search')

RameshVel
źródło
2
Miły. Kod należy do domeny publicznej, więc nie musisz nawet dołączać komentarzy.
Muhd,
4
Dobre rozwiązanie, ale nie zadziała, jeśli zdarzy ci się testować przez plik: //
kampsj
1
Z czym to wszystko ma wspólnego, @kampsj
RameshVel,
3
Cześć @kampsj, testowanie z file://protokołem spowoduje, że znacznie więcej rzeczy nie będzie działać. Możesz stworzyć bardzo szybki i łatwy statyczny serwer HTML za pomocą node.js. stackoverflow.com/questions/16333790/…
Jess
2
Ta wtyczka nie jest już obsługiwana, a sam autor sugeruje użycie innych wtyczek.
JanErikGunnar
77

Znalazłem ten klejnot od naszych przyjaciół w SitePoint. https://www.sitepoint.com/url-parameters-jquery/ .

Korzystanie z PURE jQuery. Właśnie tego użyłem i zadziałało. Trochę to poprawiłem, na przykład sake.

//URL is http://www.example.com/mypage?ref=registration&[email protected]

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('ref')); //registration
console.log($.urlParam('email')); //[email protected]

Używaj, jak chcesz.

ClosDesign
źródło
Wspaniały. Dzięki! Myślę, że nie potrzebujesz ostatniego zamykającego tagu nawiasu klamrowego.
bhtabor,
Ach tak, masz rację. Edytował post. To zostało po niektórych stwierdzeniach if w moim kodzie. Dzięki.
ClosDesign
1
Powinieneś użyć window.location.search zamiast .href - w przeciwnym razie dobrze.
BrainSlugs83
4
Zamiast tego results[1] || 0musisz zrobić, jeśli (wyniki) {return results [1]} return 0; Parametry zapytania bcoz mogą w ogóle nie występować. Modyfikacja obejmie wszystkie ogólne przypadki.
myDoggyWritesCode
1
Co robisz, jeśli masz coś takiego https://example.com/?c=Order+ID? Ten znak plus nadal pozostaje na tej funkcji.
Volomike
47

To nie jest mój przykładowy kod, ale używałem go w przeszłości.

//First Add this to extend jQuery

    $.extend({
      getUrlVars: function(){
        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;
      },
      getUrlVar: function(name){
        return $.getUrlVars()[name];
      }
    });

    //Second call with this:
    // Get object of URL parameters
    var allVars = $.getUrlVars();

    // Getting URL var by its name
    var byName = $.getUrlVar('name');
Rob Nield
źródło
2
Nie powinieneś dzielić na „=”, jest technicznie w porządku, aby drugi znak równości był wartością dowolnej pary klucz / wartość. - Tylko pierwszy napotkany znak równości (na parę klucz / wartość) powinien być traktowany jako separator. (Ponadto znak równości nie jest ściśle wymagany; można mieć klucz bez wartości.)
BrainSlugs83
Czyste rozwiązanie. W moim przypadku zadziałało idealnie.
JF Gagnon
$ .extend ({getUrlVars: function () {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 (' = '); var k = hash.shift (); vars.push (k); vars [k] = hash.join ("");} return vars;}, getUrlVar: function (name) {return $ .getUrlVars () [name];}});
Mupinc
15

Napisałem małą funkcję, w której wystarczy przeanalizować nazwę parametru zapytania. Więc jeśli masz:? Project = 12 & Mode = 200 & date = 2013-05-27 i chcesz parametr `` Mode '', musisz tylko przeanalizować nazwę `` Mode '' w funkcji:

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

// example caller:
var result =  getParameterByName('Mode');
Plippie
źródło
Jeśli twoje imię nie zawiera śmieci, możesz porzucić pierwsze wyrażenie regularne i lepiej zacząć od lokalizacji. Szukaj
mplungjan
7

Opierając się na powyższej odpowiedzi @Rob Neild, oto czysta adaptacja JS, która zwraca prosty obiekt zdekodowanych parametrów ciągu zapytania (bez% 20 itd.).

function parseQueryString () {
  var parsedParameters = {},
    uriParameters = location.search.substr(1).split('&');

  for (var i = 0; i < uriParameters.length; i++) {
    var parameter = uriParameters[i].split('=');
    parsedParameters[parameter[0]] = decodeURIComponent(parameter[1]);
  }

  return parsedParameters;
}

źródło
Nie widziałem żadnych błędów przy użyciu tego kodu. Jakiej przeglądarki używasz? Przetestowałem to z obecnymi przeglądarkami Firefox, Chrome i Safari.
Przepraszam, źle to przeczytałem. Myślałem, że widziałem, jak wywołuje metodę na czymś, co zwracało undefined. Więc tak naprawdę działa tylko raz, kiedy nie musi. Kiedy wyszukiwanie jest "". I dostajesz {"": "undefined"}
Jerinaw,
Tak. Przydałoby się to prawdopodobnie rafinacji.
1

Napisane w Vanilla Javascript

     //Get URL
     var loc = window.location.href;
     console.log(loc);
     var index = loc.indexOf("?");
     console.log(loc.substr(index+1));
     var splitted = loc.substr(index+1).split('&');
     console.log(splitted);
     var paramObj = [];
     for(var i=0;i<splitted.length;i++){
         var params = splitted[i].split('=');
         var key = params[0];
         var value = params[1];
         var obj = {
             [key] : value
         };
         paramObj.push(obj);
         }
    console.log(paramObj);
    //Loop through paramObj to get all the params in query string.
manish Prasad
źródło
1
function parseQueryString(queryString) {
    if (!queryString) {
        return false;
    }

    let queries = queryString.split("&"), params = {}, temp;

    for (let i = 0, l = queries.length; i < l; i++) {
        temp = queries[i].split('=');
        if (temp[1] !== '') {
            params[temp[0]] = temp[1];
        }
    }
    return params;
}

Używam tego.

donvercety
źródło