Bagaimana saya bisa mendapatkan nilai string kueri dalam JavaScript?

2697

Apakah ada cara tanpa plugin untuk mengambil nilai string kueri melalui jQuery (atau tanpa)?

Jika ya, bagaimana caranya? Jika tidak, apakah ada plugin yang dapat melakukannya?

Ripounet
sumber
Saya menggunakan plugin getUrlParam yang dijelaskan dalam jQuery-Plugin - getUrlParam (versi 2) .
koma
69
Sebuah javascript polos solusi tanpa regex: css-tricks.com/snippets/javascript/get-url-variables
Lorenzo Polidori
6
Meskipun solusi teratas untuk pertanyaan ini pantas mendapatkan popularitasnya karena pengamatannya yang sangat baik bahwa jQuery tidak diperlukan, metodenya untuk menciptakan ekspresi reguler baru dan mem-parsing string kueri untuk setiap parameter yang diinginkan sangat tidak efisien. Solusi yang jauh lebih efisien (dan serbaguna) telah ada sejak lama, misalnya dalam artikel ini dicetak ulang di sini: htmlgoodies.com/beyond/javascript/article.php/11877_3755006_3/…
Joseph Myers
1
kemungkinan duplikat string kueri JavaScript
4
Joseph, "pengamatan sempurna bahwa jQuery tidak diperlukan"? Tentu itu tidak diperlukan. Semuanya jQuery tidak, itu menggunakan JavaScript. Orang tidak menggunakan jQuery karena ia melakukan hal-hal yang tidak bisa dilakukan JavaScript. Inti dari jQuery adalah kenyamanan.
Vladimir Kornea

Jawaban:

8328

Pembaruan: Sep-2018

Anda dapat menggunakan URLSearchParams yang sederhana dan memiliki dukungan browser yang layak (tetapi tidak lengkap) .

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

Asli

Anda tidak perlu jQuery untuk tujuan itu. Anda dapat menggunakan hanya beberapa JavaScript murni:

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, ' '));
}

Pemakaian:

// 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)


Catatan: Jika suatu parameter hadir beberapa kali ( ?foo=lorem&foo=ipsum), Anda akan mendapatkan nilai pertama ( lorem). Tidak ada standar tentang hal ini dan penggunaannya bervariasi, lihat misalnya pertanyaan ini: Posisi otoritatif dari kunci permintaan HTTP GET duplikat .
CATATAN: Fungsi ini case-sensitive. Jika Anda lebih suka nama parameter case-insensitive, tambahkan pengubah 'i' ke RegExp


Ini adalah pembaruan berdasarkan spesifikasi URLSearchParams baru untuk mencapai hasil yang sama secara lebih ringkas. Lihat jawaban berjudul " URLSearchParams " di bawah.

Code Spy
sumber
131
Bagaimana fungsi ini menangani http://www.mysite.com/index.php?x=x1&x=x2&x=x3Nilai bidang xini ambigu.
dpp
94
ini juga tidak menangani kunci multi-nilai , yang juga legal.
hurrymaplelad
17
Mengapa Anda menggunakan ekspresi reguler untuk ini?
Ry-
28
Untuk pertanyaan awal ?mykey=0&m.+key=1, panggilan getParameterByName("m.+key")akan kembali 0sebagai gantinya 1. Anda perlu melarikan diri dari metakarakter ekspresi reguler namesebelum membangun ekspresi reguler Anda. Dan Anda hanya perlu menelepon .replace()sekali dengan menggunakan bendera global dan menggunakan "\\$&"sebagai ekspresi pengganti. Anda harus mencari location.searchalih-alih location.href. Jawaban dengan lebih dari 400 upvotes harus menjelaskan perincian ini.
gilly3
7
Anda tidak perlu jQuery untuk itu atau tujuan lain apa pun. Anda sebenarnya tidak PERLU itu.
gztomas
1708

Beberapa solusi yang diposting di sini tidak efisien. Mengulang pencarian ekspresi reguler setiap kali skrip perlu mengakses parameter sama sekali tidak perlu, satu fungsi tunggal untuk membagi parameter menjadi objek gaya array asosiatif sudah cukup. Jika Anda tidak bekerja dengan API Riwayat HTML 5, ini hanya diperlukan satu kali per halaman dimuat Saran lain di sini juga gagal memecahkan kode URL dengan benar.

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]);
})();

Contoh querystring:

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

Hasil:

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

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

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

Ini dapat dengan mudah ditingkatkan untuk menangani string kueri gaya array juga. Contohnya ada di sini , tetapi karena parameter gaya array tidak didefinisikan dalam RFC 3986 saya tidak akan mencemari jawaban ini dengan kode sumber. Bagi mereka yang tertarik dengan versi "tercemar", lihat jawaban campbeln di bawah ini .

Juga, sebagaimana ditunjukkan dalam komentar, ;adalah pembatas hukum untuk key=valuepasangan. Itu akan membutuhkan regex yang lebih rumit untuk ditangani ;atau &, yang saya pikir tidak perlu karena jarang ;digunakan dan saya akan mengatakan lebih tidak mungkin bahwa keduanya akan digunakan. Jika Anda perlu mendukung ;alih-alih &, cukup tukar di regex.


Jika Anda menggunakan bahasa preprocessing sisi-server, Anda mungkin ingin menggunakan fungsi JSON aslinya untuk melakukan pekerjaan berat untuk Anda. Misalnya, dalam PHP Anda dapat menulis:

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

Jauh lebih sederhana!

DIPERBARUI

Kemampuan baru adalah mengambil params yang diulang sebagai berikut myparam=1&myparam=2. Tidak ada spesifikasi , namun, sebagian besar pendekatan saat ini mengikuti generasi array.

myparam = ["1", "2"]

Jadi, ini adalah pendekatan untuk mengelolanya:

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]);
        }
    }
})();
Andy E
sumber
11
jika Anda melakukan aplikasi yang sangat ajax, maka Anda mungkin menggunakan hash (#) untuk "mengaktifkan tombol kembali" ... dalam hal itu querystring akan berubah sepanjang waktu (lihat bagaimana facebook melakukannya). .. meskipun solusi ini mengabaikan hal-hal yang datang setelah # anways ...
Nick Franceschina
100
@Nick: Apa pun setelah hash berada di window.location.hashproperti, yang terpisah dari window.location.searchproperti. Jika hash berubah, itu tidak mempengaruhi querystring sama sekali.
Andy E
27
Jangan lupa ;adalah pembatas hukum untuk key=valuepasangan GET . Ini jarang terjadi, tetapi perlu 5 detik untuk mengimplementasikannya.
alex
4
Agar adil, tidak ada format khusus untuk string kueri yang ditentukan oleh RFC3986. ?a=b&c=dadalah konvensional, dan rekomendasi W3C untuk formulir web, tetapi spesifikasi URI hanya menentukan query = *( pchar / "/" / "?" ).
Matthew Gilliard
21
Bagi kita yang menggunakan pengaturan JSHint yang cukup ketat, tukarkan while(match = search.exec(query))denganwhile((match = search.exec(query)) !== null)
craigts
1283

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;
                }, {}
            )
        : {}
};

Tanpa 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('&'));

Dengan URL seperti ?topic=123&name=query+string, yang berikut akan kembali:

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

Metode Google

Merobek kode Google, saya menemukan metode yang mereka gunakan: 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
}

Itu dikaburkan, tetapi itu bisa dimengerti. Tidak berfungsi karena beberapa variabel tidak terdefinisi.

Mereka mulai mencari parameter pada url dari ?dan juga dari hash #. Kemudian untuk setiap parameter mereka berpisah dalam tanda sama b[f][p]("=")(yang terlihat seperti indexOf, mereka menggunakan posisi char untuk mendapatkan kunci / nilai). Setelah dipecah mereka memeriksa apakah parameter memiliki nilai atau tidak, jika sudah maka mereka menyimpan nilai d, jika tidak mereka hanya melanjutkan.

Pada akhirnya objek ddikembalikan, penanganan melarikan diri dan +tanda. Objek ini seperti milik saya, memiliki perilaku yang sama.


Metode saya sebagai plugin 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);

Pemakaian

//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));

Tes kinerja (metode split terhadap metode regex) ( jsPerf )

Kode persiapan: deklarasi metode

Pisahkan kode uji

var qs = window.GetQueryString(query);

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

Regex kode uji

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

Pengujian di Firefox 4.0 x86 pada Windows Server 2008 R2 / 7 x64

  • Metode split : 144.780 ± 2.17% tercepat
  • Metode Regex : 13.891 ± 0,85% | 90% lebih lambat
BrunoLM
sumber
1
Ini juga merupakan pendekatan yang bagus, pemisahan string alih-alih menggunakan ekspresi reguler. Ada beberapa hal yang perlu ditunjukkan :-) 1. unescapeadalah fungsi yang sudah usang dan diganti dengan decodeURIComponent(), perhatikan bahwa tidak satu pun dari fungsi-fungsi ini akan dengan benar memecahkan kode a +ke karakter spasi. 2. Anda harus mendeklarasikan hasilnya sebagai objek, bukan array karena JavaScript tidak memiliki array asosiatif, per se, dan array yang Anda deklarasikan diperlakukan sebagai objek dengan menetapkan properti yang dinamai padanya.
Andy E
55
Ingin tahu mengapa Anda menjadikan ini plugin jQuery ketika tidak memiliki kode khusus jQuery?
zachleat
63
@ zachleat jika Anda tidak memiliki kerangka kerja, fungsi Anda hanya akan tersebar di kode Anda. Jika Anda memperluas jQuery Anda akan memiliki ruang lingkup untuk fungsi Anda, itu tidak akan melayang di suatu tempat dalam kode Anda. Saya pikir itu adalah satu-satunya alasan.
BrunoLM
6
Ini adalah versi jQuery yang di- tweak untuk melewati JSLint (setidaknya target semi-moving JSLint.com pada 2011-06-15). Kebanyakan hanya memindahkan hal-hal untuk menenangkan The Crockford.
patridge
3
Sebagai @BenjaminGruenbaum bercanda, saya juga tidak begitu mengerti tentang tolok ukur kinerja penguraian URL. Jika ini dibuat menjadi modul JavaScript isomorfik yang dapat dipanggil dari Node ke, katakanlah, parse log, maka ya. Tetapi menggunakannya untuk mengekstrak parameter URL dari window.locationmembuat masalah kinerja diperdebatkan, mengingat bahwa klien menavigasi ke URL jauh, jauh lebih mahal.
Dan Dascalescu
659

Versi perbaikan dari jawaban Artem Barger :

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

Untuk informasi lebih lanjut tentang peningkatan, lihat: http://james.padolsey.com/javascript/bujs-1-getparameterbyname/

James
sumber
23
Jika Anda ingin memperpendeknya sedikit lagi, Anda bisa menghapus syarat ternary dan menggantinya dengan sedikit hubungan pendek pada baris terakhir - return match && decodeURIComponent(match[1].replace(/\+/g, ' '));.
Andy E
Ini mengembalikan nulljika parameter tidak diikuti oleh '='. Anda dapat menambahkan if (!RegExp('[?&]'+name+'(&.*)?$').exec(window.location.search)) return false;untuk membuatnya kembali boolean falsejika parameter tidak ada sama sekali.
commonpike
9
Saya akan menggunakan newawalan saat membuat regex:var match = new RegExp('...
Patrick Berkeley
2
Bug IE11: IE memutuskan untuk menambahkan nilai yang dikembalikan dengan karakter ascii 8206 (hex: 200E - "karakter kiri-ke-kanan"). Saya menghabiskan lebih dari 6 jam untuk menemukan ini! ventilasi terapeutik .... untuk memperbaiki, tempelkan ke akhir baris terakhir:.replace('\u200E', '')
JayRO-GreyBeard
Di chrome pada mac setidaknya (mungkin browser lain juga) nilai terakhir mendapatkan tanda '/' ditambahkan. Jadi saya memodifikasi regex untuk mengabaikannya. var results = new RegExp('[\\?&]' + name + '=([^&#/]*)').exec(url);
CaseyB
594

URLSearchParams

Firefox 44+, Opera 36+, Edge 17+, Safari 10.3+ dan Chrome 49+ mendukung API URLSearchParams :

Ada polyfill URLSearchParams yang disarankan google untuk versi stabil IE.

Ini tidak distandarisasi oleh W3C , tetapi itu adalah standar hidup oleh WhatWG .

Anda dapat menggunakannya di location:

let params = new URLSearchParams(location.search);

atau

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

Atau tentu saja di URL apa pun:

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

Anda bisa mendapatkan params juga menggunakan .searchParamsproperti steno pada objek URL, seperti ini:

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

Anda membaca / parameter yang ditetapkan melalui get(KEY), set(KEY, VALUE), append(KEY, VALUE)API. Anda juga dapat mengulangi semua nilai for (let p of params) {}.

Sebuah implementasi referensi dan halaman sampel yang tersedia untuk audit dan pengujian.

Paul Sweatte
sumber
Kedua downvoter itu mungkin melewatkan (seperti yang baru saja saya lakukan) fakta bahwa Anda harus menggunakan .getbukan hanya.
Nakilon
20
Anda sebenarnya tidak perlu slice(1)aktif .search, Anda bisa menggunakannya langsung. URLSearchParams dapat menangani yang utama ?.
Jason C
URLSearchParamstidak baik karena tidak mengembalikan nilai aktual dari parameter URL.
Melab
Ini new URL('https://example.com?foo=1&bar=2') tidak berfungsi untuk url androidfile:///android_asset/...
shah
@Melab ini masih bagus karena menyediakan API sederhana untuk semua regexing aneh di jawaban lain di sini. Tetapi juga mengira saya bahwa id tidak melakukan window.location.search secara default dan tidak ada cara untuk memperbarui url saat ini termasuk.
Damon
400

Hanya rekomendasi lain. Plugin Purl memungkinkan untuk mengambil semua bagian URL, termasuk jangkar, host, dll.

Ini dapat digunakan dengan atau tanpa jQuery.

Penggunaannya sangat sederhana dan keren:

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'

Namun, pada 11 November 2014, Purl tidak lagi dipertahankan dan penulis merekomendasikan untuk menggunakan URI.js sebagai gantinya. Plugin jQuery berbeda karena berfokus pada elemen - untuk penggunaan dengan string, cukup gunakan URIlangsung, dengan atau tanpa jQuery. Kode serupa akan terlihat seperti itu, dokumen lebih lengkap di sini :

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'
AlfaTeK
sumber
7
Pada saat penulisan purl tidak lagi dipertahankan dan pengelola sebelumnya menyarankan uri.js
Dan Pantry
238

tl; dr

Solusi cepat dan lengkap , yang menangani kunci multinilai dan karakter yang disandikan .

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)})
Multi-baris:
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
})

Apa semua kode ini ...
"null-coalescing" , evaluasi hubung singkat
ES6 Penghancuran tugas , fungsi Panah , string Templat

Contoh:
"?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"



Baca lebih lanjut ... tentang solusi JavaScript Vanilla.

Untuk mengakses berbagai bagian penggunaan URL location.(search|hash)

Solusi termudah (dummy)

var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
  • Menangani kunci kosong dengan benar.
  • Mengganti multi-kunci dengan nilai terakhir ditemukan.
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined

Kunci multi-nilai

Pemeriksaan kunci sederhana (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]]})
  • Sekarang kembalikan array .
  • Nilai akses oleh qd.key[index]atauqd[key][index]
> qd
a: ["1", "5"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined]

Karakter yang dikodekan?

Gunakan decodeURIComponent()untuk pemisahan kedua atau kedua .

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]})
Contoh:
"?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"]



Dari komentar

* !!! Harap dicatat, itu decodeURIComponent(undefined)mengembalikan string "undefined". Solusinya terletak pada penggunaan sederhana &&, yang memastikan bahwa decodeURIComponent()tidak dipanggil pada nilai yang tidak ditentukan. (Lihat "solusi lengkap" di atas.)

v = v && decodeURIComponent(v);


Jika querystring kosong ( location.search == ""), hasilnya agak menyesatkan qd == {"": undefined}. Disarankan untuk memeriksa querystring sebelum meluncurkan fungsi parsing likeso:

if (location.search) location.search.substr(1).split("&").forEach(...)
Qwerty
sumber
1
Bagus. Satu-satunya hal yang saya akan ubah - adalah jika tidak ada lebih dari satu nilai untuk kunci, tidak perlu untuk menjadi array. Gunakan hanya array jika ada lebih dari satu nilai per kunci.
Pavel Nikolov
2
@ PavelNikolov Saya pikir itu akan memperkenalkan kesulitan mendapatkan terkadang array dan terkadang nilai. Anda harus memeriksanya terlebih dahulu, sekarang Anda hanya memeriksa panjangnya, karena Anda akan menggunakan siklus untuk mengambil nilai-nilai itu. Juga ini dimaksudkan sebagai solusi termudah, tetapi fungsional, di sini.
Qwerty
@katsh Ya memang, ini berfungsi di> = IE9, namun, Anda dapat mengajarkan prosesor javascript Anda array.forEach()dengan menyuntikkan kode tertentu di awal skrip Anda. lihat Polyfill developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Qwerty
1
Ratakan sedikit agar mudah dibaca, dibuat menjadi fungsi, dan digunakan kembali panggilan terpisah: function parseQueryString () {var qd = {}; location.search.substr (1) .split ("&"). forEach (fungsi (item) {var parts = item.split ("="); var k = bagian [0]; var v = decodeURIComponent (bagian [ 1]); (k dalam qd)? Qd [k] .push (v): qd [k] = [v,]}); qd kembali; }
Casey
1
decodeDocumentURI (undefined) mengembalikan "undefined" bukan undefined. Patch fungsional tetapi tidak terlalu elegan: 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] })
loop
218

Roshambo di snipplr.com memiliki skrip sederhana untuk mencapai hal ini yang dijelaskan dalam Dapatkan URL Parameter dengan jQuery | Ditingkatkan . Dengan skripnya, Anda juga dapat dengan mudah menarik hanya parameter yang Anda inginkan.

Inilah intinya:

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

Kemudian dapatkan parameter Anda dari string kueri.

Jadi jika URL / string kueri itu xyz.com/index.html?lang=de.

Panggil saja var langval = $.urlParam('lang');, dan Anda sudah mendapatkannya.

UZBEKJON juga memiliki posting blog yang luar biasa, Dapatkan parameter URL & nilai dengan jQuery .

brandonjp
sumber
13
dengan jQuery tampaknya berarti namespace fungsi ke objek jQuery. Juga, mengapa nilai tidak valid 0? Tentu, saya bisa menggunakan pemeriksaan kesetaraan yang ketat, tetapi bukankah seharusnya demikian null?
alex
Sepakat. Ini berfungsi seperti referensi variabel javascript normal seperti itu (kecuali mungkin mengembalikan tidak terdefinisi akan lebih akurat).
Isochronous
'nama' tidak diloloskan dengan benar, hanya disuntikkan langsung ke RegExp. Ini gagal. Seperti yang dikatakan orang lain, sulit dipercaya jawaban ini menciptakan kembali roda dan mendapatkan begitu banyak suara, ketika ini harus diimplementasikan di perpustakaan yang sudah teruji dengan baik.
Triynko
167

Jika Anda menggunakan jQuery, Anda dapat menggunakan perpustakaan, seperti jQuery BBQ: Back Button & Query Library .

... jQuery BBQ menyediakan .deparam()metode lengkap , bersama dengan kedua manajemen negara hash, dan fragmen / kueri string menguraikan dan menggabungkan metode utilitas.

Sunting: Menambahkan Contoh Deparam:

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

Jika Anda hanya ingin menggunakan JavaScript biasa, Anda dapat menggunakan ...

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

})();​

Karena API Riwayat HTML yang baru dan secara khusus history.pushState()dan history.replaceState(), URL dapat berubah yang akan membatalkan cache parameter dan nilainya.

Versi ini akan memperbarui cache parameter internal setiap kali sejarah berubah.

alex
sumber
100

Cukup gunakan dua pemisahan :

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

Saya membaca semua jawaban sebelumnya dan lebih lengkap. Tapi saya pikir itu adalah metode paling sederhana dan lebih cepat. Anda dapat memeriksa di benchmark jsPerf ini

Untuk mengatasi masalah dalam komentar Rup, tambahkan split bersyarat dengan mengubah baris pertama menjadi dua di bawah. Tetapi akurasi absolut berarti sekarang lebih lambat daripada regexp (lihat 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;
}

Jadi, jika Anda tahu Anda tidak akan menemui kasus balasan Rup, ini menang. Kalau tidak, regexp.

Atau jika Anda memiliki kontrol querystring dan dapat menjamin bahwa nilai yang Anda coba dapatkan tidak akan pernah mengandung karakter URL yang dikodekan (memiliki nilai ini akan menjadi ide yang buruk) - Anda dapat menggunakan versi yang sedikit lebih sederhana dan mudah dibaca berikut ini. dari opsi 1:

    function getQueryStringValueByName(name) {
        var queryStringFromStartOfValue = location.search.split(name + '=')[1];
         return queryStringFromStartOfValue !== undefined ? queryStringFromStartOfValue.split('&')[0] : null;
Martin Borthiry
sumber
7
Sangat rapi! Namun tidak akan berfungsi jika Anda memiliki nilai sebelumnya dengan nama kunci yang diakhiri dengan yang Anda inginkan, misalnya get('value')pada http://the-url?oldvalue=1&value=2.
Rup
3
Namun, jika Anda tahu nama parameter mengharapkan, ini akan menjadi pendekatan yang lebih cepat.
Martin Borthiry
Diedit: Jika Anda hanya menguji halfkebenaran, ini mengembalikan nol untuk parameter kosong seperti ?param=. Seharusnya mengembalikan string kosong dalam kasus ini, dan memeriksa half !== undefinedmenyelesaikannya.
philh
Keren! Saya membuat satu function get(param){return decodeURIComponent((location.search.split(param+'=')[1]||'').split('&')[0])}
kalimat
Saya harus mengubah baris kedua return half !== undefined ? decodeURIComponent(half[1].split('&')[0]) : null;untuk membuatnya bekerja
divillysausages
95

Inilah langkah saya untuk membuat solusi sempurna Andy E menjadi plugin jQuery lengkap:

;(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);

Sintaksnya adalah:

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

Terbaik dari kedua dunia!

Ryan Phelan
sumber
76

Jika Anda melakukan lebih banyak manipulasi URL daripada hanya mengurai querystring, Anda dapat menemukan URI.js bermanfaat. Ini adalah perpustakaan untuk memanipulasi URL - dan dilengkapi dengan semua lonceng dan peluit. (Maaf untuk iklan mandiri di sini)

untuk mengkonversi pertanyaan Anda menjadi peta:

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

(URI.js juga "perbaikan" querystrings buruk seperti ?&foo&&bar=baz&untuk ?foo&bar=baz)

rodneyrehm
sumber
// diperlukan src / URI.fragmentURI.js untuk dimuat
JoeB
1
+1 URI.js adalah plugin kecil yang bagus. Anda juga dapat melakukan var data = URI.parseQuery('?foo=bar&bar=baz&foo=world');untuk hasil yang sama ( dokumen ).
Yarin
62

Saya suka solusi Ryan Phelan . Tapi saya tidak melihat ada gunanya memperpanjang jQuery untuk itu? Tidak ada penggunaan fungsionalitas jQuery.

Di sisi lain, saya suka fungsi bawaan di Google Chrome: window.location.getParameter.

Jadi mengapa tidak menggunakan ini? Oke, browser lain tidak punya. Jadi mari kita buat fungsi ini jika tidak ada:

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

Fungsi ini lebih atau kurang dari Ryan Phelan, tetapi dibungkus berbeda: nama yang jelas dan tidak ada ketergantungan perpustakaan javascript lainnya. Lebih lanjut tentang fungsi ini di blog saya .

Anatoly Mironov
sumber
3
Sepertinya window.location.getParameter () telah dihapus dari Chrome.
mhenry1384
54

Berikut adalah cara cepat untuk mendapatkan objek yang mirip dengan array $ _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;
}

Pemakaian:

var $_GET = get_query();

Untuk string kueri x=5&y&z=hello&x=6ini mengembalikan objek:

{
  x: "6",
  y: undefined,
  z: "hello"
}
Paulpro
sumber
jika Anda memerlukannya sebagai plugin jQuery, ini dia: (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);dan gunakan seperti ini:$.get_query()
tim
Terima kasih. Saya juga akhirnya menggunakan ini. Saya menambahkan ini sebelum pernyataan pengembalian Anda: jika (param) mengembalikan hasil [param], dengan cara itu saya juga dapat melakukan get_query ('foo') jika diperlukan
sqram
1
Tidak berfungsi jika Anda memiliki hash. Sebagai contoh: test.aspx? Test = t1 # default . Akan mengembalikan {test: "t1 # default"} dan saya harapkan {test: "t1"}
Bogdan M.
@ BogdanM: memang. location.hrefharus diganti dengan location.search.
Dan Dascalescu
53

Tetap sederhana dalam kode JavaScript biasa:

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

Sebut saja dari mana saja dalam kode JavaScript:

var result = qs('someKey');
sagivo
sumber
1
Saya pikir Anda melakukan sesuatu yang serupa dengan saya, tetapi saya pikir pendekatan saya JAUH simplier stackoverflow.com/a/21152762/985454
Qwerty
Biarkan saya memperkenalkan Anda (tolong drumroll) window.location.search!
ErikE
46

Ini semua adalah jawaban yang bagus, tetapi saya membutuhkan sesuatu yang sedikit lebih kuat, dan saya pikir Anda semua mungkin ingin memiliki apa yang saya buat.

Ini adalah metode perpustakaan sederhana yang melakukan pembedahan dan manipulasi parameter URL. Metode statis memiliki sub metode berikut yang dapat dipanggil pada URL subjek:

  • dapatkanHost
  • getPath
  • getHash
  • setHash
  • getParams
  • getQuery
  • setParam
  • getParam
  • hasParam
  • hapusParam

Contoh:

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>');
meagar
sumber
44

Dari MDN :

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

alert(loadPageVar("name"));
orip
sumber
39

Golf kode:

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

Tampilkan itu!

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

Di Mac saya: test.htm?i=can&has=cheezburgermenampilkan

0:can
1:cheezburger
i:can
has:cheezburger
shanimal
sumber
9
Saya suka jawaban Anda, terutama betapa ringkasnya skrip, tetapi Anda mungkin harus menggunakan komponen decodeURIC. Lihat xkr.us/articles/javascript/encode-compare dan stackoverflow.com/questions/619323/…
pluckyglen
39

Saya sering menggunakan ekspresi reguler, tetapi tidak untuk itu.

Tampaknya lebih mudah dan lebih efisien bagi saya untuk membaca string kueri sekali di aplikasi saya, dan membangun objek dari semua pasangan kunci / nilai seperti:

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

Untuk URL seperti http://domain.com?param1=val1&param2=val2Anda bisa mendapatkan nilainya nanti di kode Anda sebagai search.param1dan search.param2.

Mic
sumber
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
Jet
sumber
5
Ini adalah pendekatan yang menarik, mengembalikan array yang berisi nilai dari parameter yang ditentukan. Itu memang memiliki setidaknya satu masalah - URL tidak benar decoding nilai-nilai, dan URL harus menyandikan nama parameter yang digunakan dalam pertandingan juga. Ini akan berfungsi pada string kueri sederhana dalam bentuknya yang sekarang. ps jangan lupa untuk menggunakan kata kunci var ketika mendeklarasikan variabel dalam untuk pernyataan.
Andy E
38

Metode Roshambo jQuery tidak menangani URL decode

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

Baru saja menambahkan kemampuan itu sambil menambahkan dalam pernyataan kembali

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

Sekarang Anda dapat menemukan inti yang diperbarui:

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

Saya suka yang ini (diambil dari 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;
}

Bekerja bagus untukku.

Tomamais
sumber
36

Inilah hasil edit saya untuk jawaban yang luar biasa ini - dengan kemampuan tambahan untuk mengurai string kueri dengan kunci tanpa nilai.

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('&'));

PENTING! Parameter untuk fungsi di baris terakhir berbeda. Itu hanya sebuah contoh bagaimana seseorang dapat mengirimkan URL yang sewenang-wenang padanya. Anda dapat menggunakan baris terakhir dari jawaban Bruno untuk mem-parsing URL saat ini.

Jadi apa sebenarnya yang berubah? Dengan url http://sb.com/reg/step1?param=hasilnya akan sama. Tetapi dengan url http://sb.com/reg/step1?param, solusi Bruno mengembalikan objek tanpa kunci, sedangkan milik saya mengembalikan objek dengan kunci paramdan undefinednilai.

skaurus
sumber
34

Saya membutuhkan objek dari string kueri, dan saya benci banyak kode. Ini mungkin bukan yang paling kuat di alam semesta, tetapi itu hanya beberapa baris kode.

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

URL seperti this.htm?hello=world&foo=barakan membuat:

{hello:'world', foo:'bar'}
tim
sumber
4
Rapi. Namun, menurut Mozilla, forEach tidak berfungsi pada IE7 atau 8 dan saya menduga itu akan gagal jika tidak ada string kueri sama sekali. Salah satu peningkatan minimal yang akan mencakup lebih banyak kasus adalah dengan decodeURIComponentnilai saat Anda menyimpannya - dan kuncinya juga, tetapi Anda cenderung menggunakan string aneh dalam hal itu.
Rup
1
Bagus dan sederhana. Tidak menangani parameter array juga ?a&b&ctetapi ini benar-benar sangat mudah dibaca (dan kebetulan mirip dengan ide pertama saya). Juga splitberlebihan tapi saya punya ikan kinerja yang lebih besar untuk menggoreng daripada membelah string 10 karakter dua kali.
cod3monk3y
1
ketika querystring adalah "? hello = world & one = a = b & two = 2" maka ketika Anda mengambil nilai 'satu' Anda hanya mendapatkan bagian sebelum yang pertama '=' dalam nilai. nilainya harus 'a = b' tetapi Anda hanya mendapatkan 'a' karena Anda membagi 'satu = a = b' pada '='. ini hanya buggy. : ((
Shawn Kovac
2
Saya akan menggunakan location.search.substr(1)alih-alih location.href.split('?')[1]menghindari mengambil hash ( #anchor) bersama dengan parameter permintaan terakhir.
mlt
Ya, izinkan saya juga memperkenalkan Anda kepada location.search!
ErikE
32

Berikut adalah versi diperpanjang dari Andy E yang terhubung "Menangani string-gaya permintaan string" -versi. Memperbaiki bug ( ?key=1&key[]=2&key[]=3; 1hilang dan diganti dengan [2,3]), membuat beberapa peningkatan kinerja kecil (mendekode ulang nilai, menghitung ulang posisi "[", dll.) Dan menambahkan sejumlah perbaikan (difungsikan, dukungan untuk ?key=1&key=2, dukungan untuk ;pembatas) . Saya meninggalkan variabel-variabel yang sangat pendek, tetapi menambahkan banyak komentar untuk membuatnya mudah dibaca (oh, dan saya menggunakan kembali vfungsi lokal, maaf jika itu membingungkan;).

Ini akan menangani querystring berikut ...

? test = Halo & orang = neek & orang [] = jeff & orang [] = jim & orang [ekstra] = john & test3 & nocache = 1398914891264

... membuatnya menjadi objek yang terlihat seperti ...

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

Seperti yang Anda lihat di atas, versi ini menangani beberapa ukuran array "salah bentuk", yaitu - person=neek&person[]=jeff&person[]=jimatau person=neek&person=jeff&person=jimkarena kunci dapat diidentifikasi dan valid (setidaknya dalam NameValueCollection.Add dotNet ):

Jika kunci yang ditentukan sudah ada dalam instance NameValueCollection contoh, nilai yang ditentukan ditambahkan ke daftar nilai yang dipisahkan koma yang ada dalam bentuk "value1, value2, value3".

Tampaknya juri agak keluar pada kunci yang diulang karena tidak ada spesifikasi. Dalam hal ini, beberapa kunci disimpan sebagai array (palsu). Tetapi perhatikan bahwa saya tidak memproses nilai berdasarkan koma menjadi array.

Kode:

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;
};
Campbeln
sumber
Untuk mendapatkan nilai string kueri, Anda dapat menggunakan fungsi "GetParameterValues" ini. Dalam hal ini Anda hanya perlu melewati nama parameter pengadukan permintaan dan itu akan mengembalikan Anda nilai $ (dokumen) .ready (function () {var bid = GetParameterValues ​​('token');}); function GetParameterValues ​​(param) {var url = decodeURIComponent (window.location.href); url = url.slice (url.indexOf ('?') + 1) .split ('&'); untuk (var i = 0; i <url.length; i ++) {var urlparam = url [i] .split ('='); if (urlparam [0] == param) {return urlparam [1]; }}
Mike Clark
1
Saya telah menggunakan ini untuk sementara waktu sekarang, dan itu sangat bagus sejauh ini. Kecuali untuk menangani susunan urlencode. Menggunakan q = decodeURIComponent(window.location.search.substring(1)),membantu melakukannya juga.
Vladislav Dimitrov
31

Ini adalah fungsi yang saya buat beberapa waktu lalu dan saya cukup senang dengannya. Ini bukan case-sensitive - yang berguna. Juga, jika QS yang diminta tidak ada, itu hanya mengembalikan string kosong.

Saya menggunakan versi terkompresi dari ini. Saya memposting tanpa kompresi untuk tipe pemula untuk lebih menjelaskan apa yang terjadi.

Saya yakin ini bisa dioptimalkan atau dilakukan secara berbeda untuk bekerja lebih cepat, tetapi selalu bekerja dengan baik untuk apa yang saya butuhkan.

Nikmati.

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);
}
Clint
sumber
Juga, lebih baik menggunakan decodeURI () atau decodeURIComponent () daripada unescape (). developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Adarsh ​​Konchady
27

Kami baru saja merilis arg.js , sebuah proyek yang ditujukan untuk menyelesaikan masalah ini untuk selamanya. Secara tradisional sudah sangat sulit, tetapi sekarang Anda dapat melakukannya:

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

atau mendapatkan semuanya:

var params = Arg.all();

dan jika Anda peduli tentang perbedaan antara ?query=truedan #hash=truekemudian Anda dapat menggunakan Arg.query()dan Arg.hash()metode.

Mat Ryer
sumber
Anda menyelamatkan saya man .. arg.js adalah solusinya tidak ada solusi yang mendapatkan nilai dari # di IE 8 .. :( siapa pun yang mencari IE8 # dapatkan dari permintaan ini solusinya ..
Dilip Rajkumar
27

Masalah dengan jawaban teratas pada pertanyaan itu adalah bahwa parameter itu tidak didukung ditempatkan setelah #, tetapi kadang-kadang diperlukan untuk mendapatkan nilai ini juga.

Saya memodifikasi jawaban untuk membiarkannya menguraikan string kueri penuh dengan tanda pagar juga:

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;
};
Ph0en1x
sumber
1
Itu menarik jika Anda membutuhkannya tetapi tidak ada standar untuk format bagian hash AFAIK sehingga tidak adil untuk menyebut itu sebagai kelemahan dari jawaban lainnya.
Rup
2
Ya saya tahu. Tetapi dalam aplikasi saya, saya mengintegrasikan navigasi js pihak ke-3, yang memiliki beberapa parameter setelah tanda pagar.
Ph0en1x
Misalnya, di halaman pencarian Google, permintaan pencarian diikuti oleh tanda pagar '#'.
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];
        }
    }
}​

Dan ini adalah bagaimana Anda dapat menggunakan fungsi ini dengan asumsi URL-nya

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

var tech = GetQueryStringParams('stringtext');
var blog = GetQueryStringParams('stringword');
gewel
sumber
Sudah ada beberapa implementasi dari pendekatan ini di sini. Paling tidak Anda perlu mendekodeUriComponent () nilai-nilai hasil. Ini juga mungkin berperilaku salah jika Anda tidak menentukan nilai, mis ?stringtext&stringword=foo.
Rup
24

Jika Anda menggunakan Browserify, Anda dapat menggunakan urlmodul dari Node.js :

var url = require('url');

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

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

Bacaan lebih lanjut: URL Node.js v0.12.2 Manual & Dokumentasi

EDIT: Anda dapat menggunakan antarmuka URL , yang cukup banyak diadopsi di hampir semua browser baru dan jika kode akan berjalan di browser lama Anda dapat menggunakan polyfill seperti ini . Berikut ini contoh kode tentang cara menggunakan antarmuka URL untuk mendapatkan parameter kueri (alias parameter pencarian)

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

Anda juga dapat menggunakan URLSearchParams untuk itu, berikut adalah contoh dari MDN untuk melakukannya dengan 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"
nkh
sumber
Dokumentasi untuk urlAPI modul ada di sini: nodejs.org/api/url.html
andrezsanchez
Ini bagus untuk pengembangan nw.js. Browserify bahkan tidak diperlukan karena sebagian besar modul simpul berfungsi seperti pada jendela nw.js. Saya telah menguji kode ini dan berfungsi seperti pesona tanpa modifikasi apa pun.
Andrew Grothe
OHH ini luar biasa! URLSearchParams berfungsi dengan sempurna. Terimakasih banyak!
Baran Emre
1
mungkin yang terbaik, tidak perlu repot dengan fungsi khusus dan perpustakaan tambahan. Ini juga tampaknya sebagian besar diadopsi oleh browser 2019.
TheWhiteLlama