Làm cách nào tôi có thể nhận các giá trị chuỗi truy vấn trong JavaScript?


2697

Có cách nào để lấy các giá trị chuỗi truy vấn thông qua jQuery (hoặc không có plugin ) không?

Nếu vậy thì thế nào? Nếu không, có một plugin có thể làm như vậy?


Tôi sử dụng plugin getUrlParam được mô tả trong jQuery-Plugin - getUrlParam (phiên bản 2) .
hôn mê

69
Một giải pháp javascript đơn giản mà không cần RegEx: css-tricks.com/snippets/javascript/get-url-variables
Lorenzo Polidori

6
Mặc dù giải pháp hàng đầu cho câu hỏi xứng đáng với sự phổ biến của nó vì quan sát tuyệt vời rằng không cần jQuery, nhưng phương pháp tạo biểu thức chính quy mới và phân tích lại chuỗi truy vấn cho mọi tham số mong muốn là cực kỳ không hiệu quả. Hiệu quả hơn (và linh hoạt) các giải pháp đã được tồn tại trong một thời gian dài, ví dụ trong bài viết này được in lại ở đây: htmlgoodies.com/beyond/javascript/article.php/11877_3755006_3/...
Joseph Myers

1
có thể trùng lặp chuỗi truy vấn JavaScript

4
Joseph, "quan sát tuyệt vời rằng jQuery không cần thiết"? Tất nhiên là không cần thiết. Mọi thứ jQuery làm, nó sử dụng JavaScript. Mọi người không sử dụng jQuery vì nó không thể làm được JavaScript. Điểm của jQuery là sự tiện lợi.
Vladimir Kornea

Câu trả lời:


8327

Cập nhật: Tháng 9-2018

Bạn có thể sử dụng URLSearchParams đơn giản và có hỗ trợ trình duyệt khá (nhưng không đầy đủ) .

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

Nguyên

Bạn không cần jQuery cho mục đích đó. Bạn chỉ có thể sử dụng một số JavaScript thuần túy:

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

Sử dụng:

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


Lưu ý: Nếu một tham số xuất hiện nhiều lần ( ?foo=lorem&foo=ipsum), bạn sẽ nhận được giá trị đầu tiên ( lorem). Không có tiêu chuẩn nào về điều này và cách sử dụng khác nhau, hãy xem ví dụ câu hỏi này: Vị trí có thẩm quyền của các khóa truy vấn HTTP GET trùng lặp .
LƯU Ý: Chức năng phân biệt chữ hoa chữ thường. Nếu bạn thích tên tham số không phân biệt chữ hoa chữ thường, hãy thêm công cụ sửa đổi 'i' vào RegExp


Đây là bản cập nhật dựa trên thông số kỹ thuật URLSearchParams mới để đạt được kết quả tương tự ngắn gọn hơn. Xem câu trả lời có tiêu đề " URLSearchParams " bên dưới.


131
Làm thế nào để chức năng này xử lý http://www.mysite.com/index.php?x=x1&x=x2&x=x3Giá trị của trường xlà mơ hồ.
dpp

94
điều này cũng không xử lý các khóa đa giá trị , cũng hoàn toàn hợp pháp.
rushmaplelad

17
Tại sao bạn sẽ sử dụng một biểu thức chính quy cho điều này?
Ry-

28
Đối với một chuỗi truy vấn ?mykey=0&m.+key=1, gọi getParameterByName("m.+key")sẽ trả về 0thay vì 1. Bạn cần phải thoát các siêu ký tự biểu thức chính quy nametrước khi xây dựng biểu thức chính quy của bạn. Và bạn chỉ cần gọi .replace()một lần bằng cách sử dụng cờ toàn cầu và sử dụng "\\$&"làm biểu thức thay thế. Bạn nên tìm kiếm trên location.searchthay vì location.href. Một câu trả lời với hơn 400 upvote nên chiếm các chi tiết này.
gilly3

7
Bạn không cần jQuery cho mục đích đó hoặc bất kỳ mục đích nào khác. Bạn thực sự không CẦN nó.
gztomas

1708

Một số giải pháp được đăng ở đây là không hiệu quả. Lặp lại tìm kiếm biểu thức chính quy mỗi khi tập lệnh cần truy cập một tham số là hoàn toàn không cần thiết, một hàm duy nhất để phân tách các tham số thành một đối tượng kiểu mảng kết hợp là đủ. Nếu bạn không làm việc với API Lịch sử HTML 5, điều này chỉ cần thiết một lần cho mỗi lần tải trang. Các đề xuất khác ở đây cũng không thể giải mã URL chính xác.

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

Ví dụ chuỗi truy vấn:

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

Kết quả:

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

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

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

Điều này có thể dễ dàng được cải thiện để xử lý các chuỗi truy vấn kiểu mảng. Một ví dụ về điều này là ở đây , nhưng vì các tham số kiểu mảng không được xác định trong RFC 3986, tôi sẽ không làm ô nhiễm câu trả lời này bằng mã nguồn. Đối với những người quan tâm đến phiên bản "bị ô nhiễm", hãy xem câu trả lời của campbeln dưới đây .

Ngoài ra, như được chỉ ra trong các ý kiến, ;là một dấu phân cách pháp lý cho key=valuecác cặp. Nó sẽ đòi hỏi một regex phức tạp hơn để xử lý ;hoặc &, điều mà tôi nghĩ là không cần thiết bởi vì nó hiếm khi ;được sử dụng và tôi sẽ nói thậm chí nhiều khả năng cả hai sẽ không được sử dụng. Nếu bạn cần hỗ trợ ;thay vì &, chỉ cần trao đổi chúng trong regex.


Nếu bạn đang sử dụng ngôn ngữ tiền xử lý phía máy chủ, bạn có thể muốn sử dụng các hàm JSON gốc của nó để thực hiện công việc nặng nhọc cho bạn. Ví dụ, trong PHP bạn có thể viết:

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

Đơn giản hơn nhiều!

CẬP NHẬT

Một khả năng mới sẽ là lấy các thông số lặp đi lặp lại như sau myparam=1&myparam=2. Không có một đặc điểm kỹ thuật , tuy nhiên, hầu hết các cách tiếp cận hiện tại tuân theo việc tạo ra một mảng.

myparam = ["1", "2"]

Vì vậy, đây là cách tiếp cận để quản lý nó:

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
nếu bạn đang làm một ứng dụng ajax'd nặng nề, thì bạn có thể đang sử dụng hàm băm (#) để "bật nút quay lại" ... trong trường hợp đó, chuỗi truy vấn sẽ thay đổi mọi lúc (xem cách facebook thực hiện). .. mặc dù các giải pháp này bỏ qua những thứ xuất hiện sau # anways ...
Nick Franceschina

100
@Nick: Bất cứ điều gì sau khi băm nằm trong window.location.hashtài sản, tách biệt với window.location.searchtài sản. Nếu hàm băm thay đổi, nó hoàn toàn không ảnh hưởng đến chuỗi truy vấn.
Andy E

27
Đừng quên ;là một dấu phân cách hợp pháp cho key=valuecác cặp GET . Nó là hiếm, nhưng phải mất 5 giây để thực hiện.
alex

4
Để công bằng, không có định dạng cụ thể cho chuỗi truy vấn được xác định bởi RFC3986. ?a=b&c=dlà thông thường và khuyến nghị W3C cho các biểu mẫu web, nhưng thông số URI chỉ xác định query = *( pchar / "/" / "?" ).
Matthew Gilliard

21
Đối với những người trong chúng tôi sử dụng một thiết lập khá nghiêm ngặt của JSHint, trao đổi while(match = search.exec(query))vớiwhile((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;
                }, {}
            )
        : {}
};

Không có 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('&'));

Với một URL như ?topic=123&name=query+string, sau đây sẽ trả về:

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

Phương pháp Google

Xé mã của Google Tôi đã tìm thấy phương pháp họ sử dụng: 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
}

Nó bị che khuất, nhưng đó là điều dễ hiểu. Nó không hoạt động vì một số biến không xác định.

Họ bắt đầu tìm kiếm các tham số trên url từ ?và cả từ hàm băm #. Sau đó, với mỗi tham số, chúng phân chia theo dấu bằng b[f][p]("=")(trông giống như indexOf, chúng sử dụng vị trí của char để lấy khóa / giá trị). Khi phân tách, họ kiểm tra xem tham số có giá trị hay không, nếu có thì họ lưu trữ giá trị của d, nếu không họ chỉ tiếp tục.

Cuối cùng, đối tượng dđược trả lại, xử lý thoát và +dấu hiệu. Đối tượng này giống như của tôi, nó có hành vi tương tự.


Phương pháp của tôi là một 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);

Sử dụng

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

Kiểm tra hiệu năng (phương pháp phân tách so với phương thức regex) ( jsPerf )

Mã chuẩn bị: khai báo phương thức

Tách mã kiểm tra

var qs = window.GetQueryString(query);

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

Mã kiểm tra Regex

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

Thử nghiệm trong Firefox 4.0 x86 trên Windows Server 2008 R2 / 7 x64

  • Phương pháp phân tách : 144.780 ± 2.17% nhanh nhất
  • Phương pháp Regex : 13.891 ± 0.85% | Chậm hơn 90%

1
Đây cũng là một cách tiếp cận tốt đẹp, tách chuỗi thay vì sử dụng các biểu thức thông thường. Có một vài điều đáng để chỉ ra, mặc dù :-) 1. unescapelà một hàm không dùng nữa và được thay thế bằng decodeURIComponent(), lưu ý rằng cả hai hàm này sẽ không giải mã chính xác +một ký tự khoảng trắng. 2. Bạn nên khai báo kết quả dưới dạng một đối tượng, thay vì một mảng vì JavaScript không có mảng kết hợp, mỗi se và mảng bạn khai báo được coi là một đối tượng bằng cách gán các thuộc tính được đặt tên cho nó.
Andy E

55
Tò mò tại sao bạn lại biến đây thành một plugin jQuery khi nó không có mã cụ thể nào của jQuery?
zachleat

63
@zachleat nếu bạn không có khung, các chức năng của bạn sẽ được trải đều trên mã của bạn. Nếu bạn mở rộng jQuery, bạn sẽ có một phạm vi cho các hàm của mình, nó sẽ không nổi ở đâu đó trong mã của bạn. Tôi nghĩ đó là lý do duy nhất.
BrunoLM

6
Đây là phiên bản jQuery được điều chỉnh để vượt qua JSLint (ít nhất là mục tiêu bán di chuyển của JSLint.com vào ngày 2011-06-15). Chủ yếu chỉ là di chuyển mọi thứ xung quanh để xoa dịu The Crockford.
patridge

3
Như @BenjaminGruenbaum đã nói đùa, tôi cũng không thấy điểm nào trong việc đánh giá hiệu suất của phân tích cú pháp URL. Nếu điều này được tạo thành một mô-đun JavaScript đẳng cấu có thể được gọi từ Node đến, giả sử, phân tích các bản ghi, thì có. Nhưng việc sử dụng nó để trích xuất các tham số URL từ window.locationviệc thực hiện bất kỳ mối quan tâm nào về hiệu suất, do khách hàng điều hướng đến URL rất xa, tốn kém hơn nhiều.
Dan Dascalescu

659

Phiên bản cải tiến của câu trả lời của Artem Barger :

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

Để biết thêm thông tin về cải tiến, hãy xem: http://james.padolsey.com/javascript/bujs-1-getparameterbyname/


23
Nếu bạn muốn rút ngắn nó thêm một chút, bạn có thể loại bỏ điều kiện ternary và thay thế nó bằng một chút ngắn mạch trên dòng cuối cùng đó - return match && decodeURIComponent(match[1].replace(/\+/g, ' '));.
Andy E

Nó trả về nullnếu tham số không được theo sau bởi '='. Bạn có thể chuẩn bị if (!RegExp('[?&]'+name+'(&.*)?$').exec(window.location.search)) return false;để làm cho nó trở lại boolean falsenếu tham số không có ở đó.
Commonpike

9
Tôi sẽ sử dụng newtiền tố khi tạo regex:var match = new RegExp('...
Patrick Berkeley

2
Lỗi IE11: IE quyết định trả trước giá trị được trả về bằng ký tự ascii 8206 (hex: 200E - "ký tự từ trái sang phải"). Tôi đã lãng phí hơn 6 giờ để tìm kiếm điều này! thông hơi trị liệu .... để khắc phục, giải quyết đến cuối dòng cuối cùng:.replace('\u200E', '')
JayRO-GreyBeard

Trong chrome trên mac ít nhất (có thể cả các trình duyệt khác nữa), giá trị cuối cùng đã được thêm '/'. Vì vậy, tôi đã sửa đổi regex để bỏ qua nó. var results = new RegExp('[\\?&]' + name + '=([^&#/]*)').exec(url);
CaseyB

594

URLSearchParams

Firefox 44+, Opera 36+, Edge 17+, Safari 10.3+ và Chrome 49+ hỗ trợ API URLSearchParams :

Có một polyfill URLSearchParams do google đề xuất cho các phiên bản IE ổn định.

Nó không được chuẩn hóa bởi W3C , nhưng nó là một mức sống của WhatWG .

Bạn có thể sử dụng nó trên location:

let params = new URLSearchParams(location.search);

hoặc là

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

Hoặc tất nhiên trên bất kỳ URL nào:

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

Bạn cũng có thể nhận thông số bằng cách sử dụng thuộc tính tốc ký .searchParamstrên đối tượng URL, như sau:

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

Bạn đọc / bộ các thông số thông qua get(KEY), set(KEY, VALUE), append(KEY, VALUE)API. Bạn cũng có thể lặp lại trên tất cả các giá trị for (let p of params) {}.

Một triển khai tham chiếu và một trang mẫu có sẵn để kiểm tra và thử nghiệm.


Hai downvoters đó có thể đã bỏ lỡ (như tôi vừa làm) thực tế là bạn phải sử dụng .getthay vì chỉ.
Nakilon

20
Bạn không thực sự cần phải slice(1)bật .search, bạn có thể sử dụng nó trực tiếp. URLSearchParams có thể xử lý hàng đầu ?.
Jason C

URLSearchParamskhông tốt vì nó không trả về giá trị thực của các tham số của URL.
Melab

Điều này new URL('https://example.com?foo=1&bar=2') không hoạt động cho url của Androidfile:///android_asset/...
shah

@Melab vẫn tốt ở chỗ nó cung cấp một API đơn giản cho tất cả các biểu thức lạ trong các câu trả lời khác ở đây. Nhưng điều kỳ lạ là id không làm window.location.search theo mặc định và không có cách nào để cập nhật url hiện tại đi kèm.
Damon

400

Chỉ là một đề nghị khác. Plugin Purl cho phép truy xuất tất cả các phần của URL, bao gồm cả neo, máy chủ, v.v.

Nó có thể được sử dụng có hoặc không có jQuery.

Cách sử dụng rất đơn giản và tuyệt vời:

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'

Tuy nhiên, kể từ ngày 11 tháng 11 năm 2014, Purl không còn được duy trì và tác giả khuyên bạn nên sử dụng URI.js thay thế. Plugin jQuery khác ở chỗ nó tập trung vào các yếu tố - để sử dụng với chuỗi, chỉ cần sử dụng URItrực tiếp, có hoặc không có jQuery. Mã tương tự sẽ trông như vậy, tài liệu đầy đủ hơn ở đây :

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
Khi viết purl không còn được duy trì và người bảo trì trước đó gợi ý uri.js
Dan Pantry

238

tl; dr

Một giải pháp nhanh chóng, đầy đủ , xử lý các khóa đa trị và các ký tự được mã hóa .

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)})
Nhiều dòng:
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
})

Tất cả mã này là gì ...
"hợp nhất null" , đánh giá ngắn mạch
ES6 Phân công cấu trúc , hàm mũi tên , chuỗi mẫu

Thí dụ:
"?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"



Đọc thêm ... về giải pháp Vanilla JavaScript.

Để truy cập các phần khác nhau của một URL sử dụng location.(search|hash)

Giải pháp dễ nhất (giả)

var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
  • Xử lý các phím trống chính xác.
  • Ghi đè nhiều khóa với giá trị cuối cùng được tìm thấy.
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined

Khóa đa giá trị

Kiểm tra chìa khóa đơn giản (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]]})
  • Bây giờ trả về mảng thay thế.
  • Truy cập giá trị bằng qd.key[index]hoặcqd[key][index]
> qd
a: ["1", "5"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined]

Ký tự được mã hóa?

Sử dụng decodeURIComponent()cho lần chia thứ hai hoặc cả hai .

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]})
Thí dụ:
"?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"]



Từ ý kiến

* * !!! Xin lưu ý rằngdecodeURIComponent(undefined) trả về chuỗi "undefined". Giải pháp nằm ở cách sử dụng đơn giản &&, đảm bảo decodeURIComponent()không được gọi trên các giá trị không xác định. (Xem phần "giải pháp hoàn chỉnh" ở trên cùng.)

v = v && decodeURIComponent(v);


Nếu chuỗi truy vấn trống ( location.search == ""), kết quả có phần sai lệchqd == {"": undefined} . Bạn nên kiểm tra chuỗi truy vấn trước khi khởi chạy chức năng phân tích cú pháp likeo:

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

1
Đẹp. Điều duy nhất tôi sẽ thay đổi - là nếu không có nhiều hơn một giá trị cho một khóa thì không cần phải là một mảng. Chỉ sử dụng mảng nếu có nhiều hơn một giá trị cho mỗi khóa.
Pavel Nikolov

2
@PavelNikolov Tôi nghĩ rằng nó sẽ giới thiệu những khó khăn đôi khi là một mảng và đôi khi là một giá trị. Bạn sẽ phải kiểm tra nó trước, bây giờ bạn chỉ kiểm tra độ dài, bởi vì bạn sẽ sử dụng các chu kỳ để truy xuất các giá trị đó. Ngoài ra, điều này có nghĩa là giải pháp dễ nhất, nhưng chức năng, ở đây.
Qwerty

@katsh Đúng vậy, nó hoạt động trong> = IE9, tuy nhiên, bạn có thể dạy bộ xử lý javascript của mình array.forEach()bằng cách tiêm một số mã nhất định vào đầu tập lệnh của bạn. xem nhà phát triển
Qwerty

1
Làm phẳng một chút để dễ đọc, được thực hiện thành một hàm và sử dụng lại lệnh gọi phân tách: function parseQueryString () {var qd = {}; location.search.substr (1) .split ("&"). forEach (function (item) {var phần = item.split ("="); var k = phần [0]; var v = decodeURIComponent (phần [ 1]); (k trong qd)? Qd [k] .push (v): qd [k] = [v,]}); trả lại qd; }
Casey

1
decodeDocumentURI (không xác định) trả về "không xác định" thay vì không xác định. Một bản vá chức năng nhưng không thanh lịch: 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] })
lặp

218

Roshambo trên snipplr.com có ​​một tập lệnh đơn giản để đạt được điều này được mô tả trong Lấy tham số URL với jQuery | Cải thiện . Với kịch bản của anh ta, bạn cũng dễ dàng lấy ra các tham số bạn muốn.

Đây là ý chính:

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

Sau đó, chỉ cần lấy tham số của bạn từ chuỗi truy vấn.

Vì vậy, nếu URL / chuỗi truy vấn là xyz.com/index.html?lang=de.

Chỉ cần gọi var langval = $.urlParam('lang');, và bạn đã có nó.

UZBEKJON cũng có một bài đăng blog tuyệt vời về vấn đề này, Nhận các tham số & giá trị URL với jQuery .


13
với jQuery dường như có nghĩa là không gian tên hàm cho đối tượng jQuery. Ngoài ra, tại sao giá trị không hợp lệ 0? Chắc chắn, tôi có thể sử dụng kiểm tra bình đẳng nghiêm ngặt, nhưng không nên null?
alex

Đã đồng ý. Nó hoạt động giống như một tham chiếu biến javascript thông thường theo cách đó (ngoại trừ việc trả về không xác định sẽ chính xác hơn).
bộ

'Tên' không được thoát đúng cách, nó chỉ được đưa trực tiếp vào RegExp. Điều này thất bại. Giống như những người khác đã nói, thật không thể tin được những câu trả lời này đang phát minh lại bánh xe và nhận được rất nhiều phiếu bầu, khi điều này nên được thực hiện trong một thư viện được thử nghiệm tốt.
Triynko

167

Nếu bạn đang sử dụng jQuery, bạn có thể sử dụng thư viện, chẳng hạn như jQuery BBQ: Nút quay lại & Thư viện truy vấn .

... jQuery BBQ cung cấp một .deparam()phương thức đầy đủ , cùng với cả quản lý trạng thái băm và phân tích chuỗi phân đoạn / truy vấn và hợp nhất các phương thức tiện ích.

Chỉnh sửa: Thêm ví dụ 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();
                  
            }
        };

Nếu bạn muốn chỉ sử dụng JavaScript đơn giản, bạn có thể sử dụng ...

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

})();​

Do API Lịch sử HTML mới và cụ thể history.pushState()history.replaceState() , URL có thể thay đổi sẽ làm mất hiệu lực bộ đệm của các tham số và giá trị của chúng.

Phiên bản này sẽ cập nhật bộ đệm nội bộ của các tham số mỗi khi lịch sử thay đổi.


100

Chỉ cần sử dụng hai phần tách :

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

Tôi đã đọc tất cả các câu trả lời trước đó và đầy đủ hơn. Nhưng tôi nghĩ đó là phương pháp đơn giản và nhanh nhất. Bạn có thể kiểm tra điểm chuẩn jsPerf này

Để giải quyết vấn đề trong bình luận của Rup, hãy thêm một phân chia có điều kiện bằng cách thay đổi dòng đầu tiên thành hai dòng bên dưới. Nhưng độ chính xác tuyệt đối có nghĩa là bây giờ nó chậm hơn regrec (xem 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;
}

Vì vậy, nếu bạn biết bạn sẽ không gặp phải trường hợp phản đối của Rup, thì chiến thắng này. Nếu không, regrec.

Hoặc nếu bạn có quyền kiểm soát chuỗi truy vấn và có thể đảm bảo rằng giá trị bạn đang cố gắng nhận sẽ không bao giờ chứa bất kỳ ký tự được mã hóa URL nào (có các giá trị này sẽ là một ý tưởng tồi) - bạn có thể sử dụng phiên bản đơn giản và dễ đọc hơn một chút sau đây của tùy chọn 1:

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

7
Rât gọn gang! Nó sẽ không hoạt động mặc dù nếu bạn có một giá trị sớm hơn với tên khóa kết thúc bằng tên bạn muốn, ví dụ như get('value')trên http://the-url?oldvalue=1&value=2.
Rupi

3
Tuy nhiên, nếu bạn biết tên tham số đang mong đợi, Đây sẽ là cách tiếp cận nhanh hơn.
Martin Borthiry

Đã chỉnh sửa: Nếu bạn chỉ kiểm tra đó halflà sự thật, điều này trả về null cho một tham số trống như ?param=. Nó sẽ trả về chuỗi rỗng trong trường hợp này và kiểm tra half !== undefinedgiải quyết điều đó.
philh

Mát mẻ! Tôi đã thực hiện một lớp lót:function get(param){return decodeURIComponent((location.search.split(param+'=')[1]||'').split('&')[0])}
niutech

Tôi đã phải thay đổi dòng thứ hai để return half !== undefined ? decodeURIComponent(half[1].split('&')[0]) : null;làm cho nó hoạt động
divillysausages 13/1/2015

95

Đây là nỗ lực của tôi trong việc biến giải pháp tuyệt vời của Andy E thành một plugin jQuery hoàn chỉnh:

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

Cú pháp là:

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

Tốt nhất của cả hai thế giới!


76

Nếu bạn đang thực hiện nhiều thao tác URL hơn là chỉ phân tích chuỗi truy vấn, bạn có thể thấy URI.js hữu ích. Đây là một thư viện để thao tác các URL - và đi kèm với tất cả các chuông và còi. (Xin lỗi vì tự quảng cáo ở đây)

để chuyển đổi chuỗi truy vấn của bạn thành bản đồ:

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

(URI.js cũng "sửa chữa" querystrings xấu thích ?&foo&&bar=baz&đến ?foo&bar=baz)


// yêu cầu src / URI.fragmentURI.js được tải
JoeB

1
+1 URI.js là một plugin nhỏ tuyệt vời. Bạn cũng có thể làm var data = URI.parseQuery('?foo=bar&bar=baz&foo=world');cho kết quả tương tự ( tài liệu ).
Yarin

62

Tôi thích giải pháp của Ryan Phelan . Nhưng tôi không thấy bất kỳ điểm nào mở rộng jQuery cho điều đó? Không có sử dụng chức năng jQuery.

Mặt khác, tôi thích chức năng tích hợp trong Google Chrome: window.location.getParameter.

Vậy tại sao không sử dụng cái này? Được rồi, các trình duyệt khác không có. Vì vậy, hãy tạo chức năng này nếu nó không tồn tại:

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

Hàm này ít nhiều từ Ryan Phelan, nhưng nó được gói khác nhau: tên rõ ràng và không phụ thuộc vào các thư viện javascript khác. Thêm về chức năng này trên blog của tôi .


3
Có vẻ như window.location.getParameter () đã bị xóa khỏi Chrome.
mhenry1384

54

Đây là một cách nhanh chóng để có được một đối tượng tương tự như mảng PHP $ _GET :

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

Sử dụng:

var $_GET = get_query();

Đối với chuỗi truy vấn, x=5&y&z=hello&x=6điều này trả về đối tượng:

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

nếu bạn cần nó như một plugin jQuery, thì đây là: (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);và sử dụng như thế này:$.get_query()
tim

Cảm ơn. Tôi cũng đã kết thúc việc sử dụng này. Tôi đã thêm điều này trước câu trả lời của bạn: if (param) return result [param], bằng cách đó tôi cũng có thể thực hiện get_query ('foo') nếu cần
sqram

1
Không hoạt động nếu bạn có băm. Ví dụ: test.aspx? Test = t1 # mặc định . Sẽ trả về {test: "t1 # default"} và tôi mong đợi {test: "t1"}
Bogdan M.

@BogdanM: thật vậy. location.hrefsẽ phải được thay thế bằng location.search.
Dan Dascalescu

53

Giữ cho nó đơn giản trong mã JavaScript đơn giản:

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

Gọi nó từ bất cứ nơi nào trong mã JavaScript:

var result = qs('someKey');

1
Tôi nghĩ rằng bạn đang làm một cái gì đó tương tự như tôi, nhưng tôi nghĩ cách tiếp cận của tôi đơn giản hơn là stackoverflow.com/a/21152762/985454
Qwerty

Hãy để tôi giới thiệu cho bạn (trống xin vui lòng) window.location.search!
ErikE

46

Đây là tất cả các câu trả lời tuyệt vời, nhưng tôi cần một cái gì đó mạnh mẽ hơn một chút, và nghĩ rằng tất cả các bạn có thể muốn có những gì tôi tạo ra.

Đây là một phương pháp thư viện đơn giản để phân tích và thao tác các tham số URL. Phương thức tĩnh có các phương thức phụ sau có thể được gọi trên URL chủ đề:

  • gethost
  • getPath
  • nhận được
  • setHash
  • getParams
  • getQuery
  • setParam
  • có được
  • hasParam
  • gỡ bỏ

Thí dụ:

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

Từ MDN :

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

alert(loadPageVar("name"));

39

Mã golf:

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

Hiển thị nó!

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

Trên máy Mac của tôi: test.htm?i=can&has=cheezburgerhiển thị

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

9
Tôi thích câu trả lời của bạn, đặc biệt là kịch bản nhỏ gọn như thế nào, nhưng có lẽ bạn nên sử dụng decodeURIComponent. Xem xkr.us/articles/javascript/encode-comparestackoverflow.com/questions/619323/
gợi

39

Tôi sử dụng biểu thức chính quy rất nhiều, nhưng không phải cho điều đó.

Tôi có vẻ dễ dàng và hiệu quả hơn khi đọc chuỗi truy vấn một lần trong ứng dụng của mình và xây dựng một đối tượng từ tất cả các cặp khóa / giá trị như:

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

Đối với một URL như http://domain.com?param1=val1&param2=val2bạn có thể nhận được giá trị của chúng sau này trong mã của bạn search.param1search.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
Đây là một cách tiếp cận thú vị, trả về một mảng chứa các giá trị từ các tham số đã chỉ định. Nó có ít nhất một vấn đề - không giải mã URL chính xác các giá trị và nó cũng cần phải mã hóa URL các tên tham số được sử dụng trùng khớp. Nó sẽ hoạt động trên các chuỗi truy vấn đơn giản ở dạng hiện tại. ps đừng quên sử dụng từ khoá var khi tuyên bố biến trong cho báo cáo.
Andy E

38

Phương pháp Roshambo jQuery không quan tâm đến việc giải mã URL

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

Chỉ cần thêm khả năng đó trong khi thêm vào câu lệnh return

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

Bây giờ bạn có thể tìm thấy ý chính cập nhật:

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

36

Tôi thích cái này (lấy từ 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;
}

Làm việc tuyệt vời cho tôi.


36

Đây là bản chỉnh sửa của tôi cho câu trả lời tuyệt vời này - có thêm khả năng phân tích chuỗi truy vấn bằng các khóa không có giá trị.

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

QUAN TRỌNG! Tham số cho chức năng đó trong dòng cuối cùng là khác nhau. Đây chỉ là một ví dụ về cách người ta có thể chuyển một URL tùy ý cho nó. Bạn có thể sử dụng dòng cuối cùng từ câu trả lời của Bruno để phân tích URL hiện tại.

Vậy chính xác điều gì đã thay đổi? Với http://sb.com/reg/step1?param=kết quả url sẽ giống nhau. Nhưng với url http://sb.com/reg/step1?param, giải pháp của Bruno trả về một đối tượng không có khóa, trong khi của tôi trả về một đối tượng có khóa paramundefinedgiá trị.


34

Tôi cần một đối tượng từ chuỗi truy vấn và tôi ghét rất nhiều mã. Nó có thể không mạnh nhất trong vũ trụ, nhưng đó chỉ là một vài dòng mã.

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

Một URL như this.htm?hello=world&foo=barsẽ tạo ra:

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

4
Khéo léo. Tuy nhiên, theo Mozilla, forEach không hoạt động trên IE7 hoặc 8 và tôi nghi ngờ rằng nó sẽ bị đổ nếu không có chuỗi truy vấn nào cả. Một cải tiến tối thiểu sẽ bao gồm nhiều trường hợp hơn là decodeURIComponentgiá trị khi bạn lưu trữ nó - và cũng có thể là khóa, nhưng bạn ít có khả năng sử dụng các chuỗi lẻ trong đó.
Rupi

1
Đẹp và đơn giản. Không xử lý các tham số mảng cũng không ?a&b&cnhưng điều này thực sự rất dễ đọc (và hoàn toàn giống với ý tưởng đầu tiên của tôi). Ngoài ra, splitnó là dư thừa nhưng tôi đã có cá hiệu suất lớn hơn để chiên hơn là chia chuỗi 10 ký tự hai lần.
cod3monk3y

1
khi chuỗi truy vấn là "? hello = world & one = a = b & Two = 2" thì khi bạn lấy giá trị của 'một', bạn chỉ nhận được phần trước '=' đầu tiên trong giá trị. giá trị của nó là 'a = b' nhưng bạn chỉ nhận được 'a' vì bạn đã tách 'one = a = b' trên '='. Điều này chỉ đơn giản là lỗi. : ((
Shawn Kovac

2
Tôi sẽ sử dụng location.search.substr(1)thay vì location.href.split('?')[1]để tránh chọn hàm băm ( #anchor) cùng với tham số truy vấn cuối cùng.
mlt

Vâng, để tôi cũng giới thiệu cho bạn location.search!
ErikE

32

Đây là phiên bản mở rộng của chuyển đổi "Xử lý chuỗi truy vấn kiểu mảng" được liên kết của Andy E. Cố định một lỗi ( ?key=1&key[]=2&key[]=3; 1bị mất và thay thế bằng [2,3]), thực hiện một vài cải tiến hiệu suất nhỏ (tái giải mã các giá trị, tính toán lại "[" vị trí, vv) và thêm một số cải tiến (chức hóa, hỗ trợ cho ?key=1&key=2, hỗ trợ cho ;delimiters) . Tôi đã để lại các biến ngắn một cách khó chịu, nhưng đã thêm các bình luận để làm cho chúng dễ đọc hơn (ồ, và tôi đã sử dụng lại vtrong các hàm cục bộ, xin lỗi nếu điều đó gây nhầm lẫn;).

Nó sẽ xử lý chuỗi truy vấn sau ...

? test = Hello & person = neek & person [] = jeff & person [] = jim & person [thêm] = john & test3 & nocache = 1398913611264

... biến nó thành một vật thể trông giống như ...

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

Như bạn có thể thấy ở trên, phiên bản này xử lý một số biện pháp của mảng "không đúng định dạng", tức là - person=neek&person[]=jeff&person[]=jimhoặc person=neek&person=jeff&person=jimlà khóa có thể nhận dạng và hợp lệ (ít nhất là trong NameValueCollection.Add của dotNet ):

Nếu khóa được chỉ định đã tồn tại trong thể hiện NameValueCollection đích, giá trị được chỉ định sẽ được thêm vào danh sách giá trị được phân tách bằng dấu phẩy hiện có ở dạng "value1, value2, value3".

Có vẻ như bồi thẩm đoàn có phần ngoài các phím lặp đi lặp lại vì không có thông số kỹ thuật. Trong trường hợp này, nhiều khóa được lưu trữ dưới dạng một mảng (giả). Nhưng xin lưu ý rằng tôi không xử lý các giá trị dựa trên dấu phẩy thành mảng.

Mật mã:

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

Để nhận các giá trị chuỗi truy vấn, bạn có thể sử dụng hàm "GetParameterValues" này. Trong trường hợp này, bạn chỉ cần truyền tên tham số khuấy truy vấn và nó sẽ trả về cho bạn giá trị $ (tài liệu). Đã (hàm () {var price = GetParameterValues ​​('token');}); chức năng GetParameterValues ​​(param) {var url = decodeURIComponent (window.location.href); url = url.slice (url.indexOf ('?') + 1) .split ('&'); for (var i = 0; i <url.length; i ++) {var urlparam = url [i] .split ('='); if (urlparam [0] == param) {return urlparam [1]; }}
Mike Clark

1
Tôi đã sử dụng điều này được một thời gian và cho đến nay nó vẫn rất tuyệt. Ngoại trừ việc xử lý các mảng urlencoding. Sử dụng q = decodeURIComponent(window.location.search.substring(1)),giúp nó làm điều đó quá.
Vladislav Dimitrov

31

Đây là một chức năng tôi đã tạo ra một thời gian trước đây và tôi khá hài lòng với. Nó không phải là trường hợp nhạy cảm - đó là tiện dụng. Ngoài ra, nếu QS được yêu cầu không tồn tại, nó chỉ trả về một chuỗi rỗng.

Tôi sử dụng một phiên bản nén của điều này. Tôi đang đăng bài không nén cho các loại người mới để giải thích rõ hơn những gì đang diễn ra.

Tôi chắc chắn rằng điều này có thể được tối ưu hóa hoặc thực hiện khác nhau để hoạt động nhanh hơn, nhưng nó luôn hoạt động tốt cho những gì tôi cần.

Thưởng thức.

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

Ngoài ra, tốt hơn là dùng decodeURI () hoặc decodeURIComponent () thay vì unescape (). developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
triệt

27

Chúng tôi vừa phát hành arg.js , một dự án nhằm giải quyết vấn đề này một lần và mãi mãi. Theo truyền thống, nó rất khó khăn nhưng bây giờ bạn có thể làm:

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

hoặc nhận được toàn bộ lô:

var params = Arg.all();

và nếu bạn quan tâm đến sự khác biệt giữa ?query=true#hash=truesau đó bạn có thể sử dụng Arg.query()Arg.hash()phương thức.


bạn đã cứu tôi .. arg.js là giải pháp không có giải pháp nào nhận được các giá trị từ # trong IE 8 .. :( bất kỳ ai đang tìm kiếm IE8 # đều nhận được yêu cầu, đây là giải pháp ..
Dilip Rajkumar

27

Vấn đề với câu trả lời hàng đầu cho câu hỏi đó là các tham số không được hỗ trợ được đặt sau #, nhưng đôi khi cũng cần có giá trị này.

Tôi đã sửa đổi câu trả lời để cho nó phân tích chuỗi truy vấn đầy đủ bằng dấu băm:

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
Điều đó thật thú vị nếu bạn cần nó nhưng không có tiêu chuẩn nào cho định dạng của phần băm AFAIK vì vậy thật không công bằng khi gọi đó là điểm yếu của câu trả lời khác.
Rup

2
Vâng tôi biết. Nhưng trong ứng dụng của tôi, tôi tích hợp điều hướng js của bên thứ 3, có một số tham số sau dấu băm.
Ph0en1x

Ví dụ: trong trang tìm kiếm của Google, truy vấn tìm kiếm được theo sau bởi dấu băm '#'.
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];
        }
    }
}​

Và đây là cách bạn có thể sử dụng chức năng này với giả sử URL là

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

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

Có một vài triển khai của phương pháp này ở đây. Ít nhất bạn cần giải mãUriComponent () các giá trị kết quả. Điều này cũng có thể hoạt động sai nếu bạn không chỉ định một giá trị, ví dụ ?stringtext&stringword=foo.
Rup

24

Nếu bạn đang sử dụng Browserify, bạn có thể sử dụng urlmô-đun từ Node.js :

var url = require('url');

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

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

Đọc thêm: URL Node.js v0.12.2 Hướng dẫn & Tài liệu

EDIT: Bạn có thể sử dụng giao diện URL , giao diện này được áp dụng khá rộng rãi trong hầu hết tất cả các trình duyệt mới và nếu mã sẽ chạy trên trình duyệt cũ, bạn có thể sử dụng một polyfill như thế này . Đây là một ví dụ mã về cách sử dụng giao diện URL để nhận các tham số truy vấn (còn gọi là tham số tìm kiếm)

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

Bạn cũng có thể sử dụng URLSearchParams cho nó, đây là một ví dụ từ MDN để làm điều đó với 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"

Tài liệu về urlAPI của mô-đun có tại đây: nodejs.org/api/url.html
andrezsanchez

Điều này là tốt cho sự phát triển của nw.js. Browserify thậm chí không cần thiết vì hầu hết các mô-đun nút hoạt động như trong cửa sổ nw.js. Tôi đã kiểm tra mã này và hoạt động như một bùa mê mà không cần sửa đổi gì.
Andrew Grothe

OHH điều này thật tuyệt vời! URLSearchParams hoạt động hoàn hảo. Cảm ơn nhiều!
Baran Emre

1
có lẽ nên được bình chọn tốt nhất, không gặp rắc rối với các chức năng tùy chỉnh và thư viện bổ sung. Nó dường như cũng được chấp nhận bởi các trình duyệt 2019.
TheWhiteLlama
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.