Chuỗi truy vấn JavaScript [đã đóng]


106

Có thư viện JavaScript nào tạo từ điển ngoài chuỗi truy vấn, ASP.NETkiểu không?

Một cái gì đó có thể được sử dụng như:

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

"chuỗi truy vấn" được gọi là cái gì khác ngoài .NETlĩnh vực? Tại sao không được location.searchchia thành một bộ sưu tập khóa / giá trị ?

CHỈNH SỬA : Tôi đã viết hàm của riêng mình, nhưng có thư viện JavaScript chính nào làm được điều này không?


3
đã tìm thấy điều này: medialize.github.com/URI.js
hươu sao



1
@davidtaubmann rằng một cái cũ hơn, nó sẽ là nghịch đảo. Buồn cười là về cơ bản họ hỏi giống nhau, nhưng do định dạng của câu hỏi, một câu hỏi được chuyển thành vinh quang của cộng đồng, và câu hỏi khác bị đóng lại là lạc đề.
Andre Figueosystemo

Câu trả lời:


11

37
Điều này phải có nguồn gốc từ jquery
gcb

@EvanMulawski Cảm ơn. Có vẻ như plugin đã biến mất. Tôi đã thêm một liên kết khác, có thể hữu ích.
Shadow2531,

Phương pháp do CMS cung cấp dễ dàng hơn và sạch hơn. Esp. nếu bạn chưa sử dụng jquery.
jcoffland

1
Bạn có thể tham khảo thư viện này để làm điều đó - github.com/Mikhus/jsurl
Mikhus

1
Đây là liên kết thích hợp: plugins.jquery.com/query-object
thexfactor

230

Bạn có thể trích xuất các cặp khóa / giá trị từ thuộc tính location.search , thuộc tính này có một phần của URL theo sau dấu? biểu tượng, bao gồm dấu? Biểu tượng.

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

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

  return result;
}

// ...
var myParam = getQueryString()["myParam"];

11
Đây không phải là một chiến thắng. Điều gì sẽ xảy ra nếu giá trị của khóa có ký tự '=' trong đó? Ví dụ: dork.com/?equation=10=2. Bạn có thể tranh luận rằng nó NÊN được mã hóa URL nhưng chắc chắn là không phải vậy. Tôi đã sai lầm khi viết một hàm ngây thơ như thế này một lần. Có nhiều hơn một trường hợp cạnh mà chức năng này giải thích.
JamesBrownIsDead

6
@James, quên đề cập rằng một vài tháng trước, tôi đã sửa đổi hàm, bây giờ nó có thể xử lý chính xác ví dụ của bạn dork.com/?equation=10=2...
CMS

2
@CMS điều này không xử lý khả năng có một mảng trong chuỗi truy vấn được biểu diễn như vậy, ?val=foo&val=bar&val=baz làm thế nào bạn có thể xử lý điều này?
Russ Bradberry

2
@RussBradberry Bạn thực sự không thể có val=foo&val=bar&val=baz; nó sẽ phải như vậyval[]=foo&val[]=bar&val[]=baz
Brian Driscoll

1
Dường như không đầy đủ đối với tôi khi giá trị của tôi có không gian và vars của tôi đã kết thúc với %20's, vì vậy tôi thay thế result[keyValuePair[0]] = keyValuePair[1] || '';vớiresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601

22

giải pháp tl; dr trên một dòng mã (ish) duy nhất sử dụng javascript vani

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

Đối với chuỗi truy vấn, ?a=1&b=2&c=3&d&enó trả về:

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

khóa đa giá trị và các ký tự được mã hóa ?

Xem câu trả lời ban đầu tại Làm cách nào để nhận giá trị chuỗi truy vấn trong JavaScript?

"?a=1&b=2&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> queryDict
a: ["1", "5", "t e x t"]
b: ["2"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

8
đó không phải là một dòng duy nhất - đó là một số dòng được định dạng không tốt!
JonnyRaa

1
Chết tiệt, tôi không biết phải nói gì ... Bạn đã hiểu tôi. Đây, có một số giải pháp nhiều dòng: `var queryDict = {}; location.search.substr (1) .split ("&"). forEach (function (item) {queryDict [item.split ("=") [0]] = item.split ("=") [1]; }); `
Qwerty

2
haha tôi thích nó! Xin lỗi, tôi đã từng làm việc với một người thường nói 'Tôi đã tìm thấy một chữ lót có dấu x' và sau đó chỉ cho bạn xem 3 dòng với các dấu ngắt dòng được thực hiện!
JonnyRaa

@JonnyLeeds Không sao, tôi biết chính xác ý bạn, nhưng sau đó, tại sao người ta lại viết từng lệnh chuỗi trên dòng mới? Sau đó, có một hàm được đưa ra dưới dạng tham số (các tham số thường được nội dòng) chỉ có một phép gán duy nhất. Nó hét lên để được nội tuyến! : D
Qwerty

1
@Qwerty, có thể là do "one-liner" của bạn nên được định dạng lại để việc đọc nó không yêu cầu cuộn ngang. Tôi đã điều chỉnh nó.
P i

8

Sau khi tìm thấy bài đăng này, khi nhìn lại bản thân, tôi nghĩ mình nên nói thêm rằng tôi không nghĩ giải pháp được nhiều người bình chọn nhất là tốt nhất. Nó không xử lý các giá trị mảng (chẳng hạn như? A = foo & a = bar - trong trường hợp này, tôi mong đợi nhận được một để trả về ['foo', 'bar']). Theo như tôi có thể nói thì không tính đến các giá trị được mã hóa - chẳng hạn như mã hóa ký tự hex trong đó% 20 đại diện cho một khoảng trắng (ví dụ:? A = Hello% 20World) hoặc biểu tượng dấu cộng được sử dụng để đại diện cho một khoảng trắng (ví dụ :? a = Hello + World).

Node.js cung cấp một giải pháp hoàn chỉnh để phân tích cú pháp chuỗi truy vấn. Nó sẽ dễ dàng lấy ra và sử dụng trong dự án của riêng bạn vì nó được cách ly khá tốt và được cấp phép dễ dàng.

Bạn có thể xem mã của nó tại đây: https://github.com/joyent/node/blob/master/lib/querystring.js

Các bài kiểm tra mà Node có có thể được xem tại đây: https://github.com/joyent/node/blob/master/test/simple/test-querystring.js Tôi khuyên bạn nên thử một số bài kiểm tra này với câu trả lời phổ biến để xem nó như thế nào. xử lý chúng.

Ngoài ra còn có một dự án mà tôi đã tham gia để đặc biệt thêm chức năng này. Nó là một cổng của mô-đun phân tích chuỗi truy vấn lib tiêu chuẩn Python. Bạn có thể tìm thấy fork của tôi tại đây: https://github.com/d0ugal/jquery.qeeree


Không chỉ mượn mã từ Node, js, mà nó rất đan xen.
alfwatt

5

Hoặc bạn có thể sử dụng thư viện sugar.js .

Từ sugarjs.com:

Object.fromQueryString (str , deep = true )

Chuyển đổi chuỗi truy vấn của một URL thành một đối tượng. Nếu deep là false, chuyển đổi sẽ chỉ chấp nhận các tham số nông (tức là không có đối tượng hoặc mảng có cú pháp []) vì chúng không được hỗ trợ phổ biến.

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

Thí dụ:

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

3

Nếu bạn có sẵn chuỗi truy vấn, hãy sử dụng:

 /**
 * @param qry the querystring
 * @param name name of parameter
 * @returns the parameter specified by name
 * @author eduardo.medeirospereira@gmail.com
 */

function getQueryStringParameter(qry,name){
    if(typeof qry !== undefined && qry !== ""){
        var keyValueArray = qry.split("&");
        for ( var i = 0; i < keyValueArray.length; i++) {
            if(keyValueArray[i].indexOf(name)>-1){
                return keyValueArray[i].split("=")[1];
            }
        }
    }
    return "";
}

2
// How about this
function queryString(qs) {
    var queryStr = qs.substr(1).split("&"),obj={};
    for(var i=0; i < queryStr.length;i++)
        obj[queryStr[i].split("=")[0]] = queryStr[i].split("=")[1];
    return obj;
}

// Usage:
var result = queryString(location.search);

Điều đó gần giống với mã "Cập nhật: không cần sử dụng regex" trong câu trả lời được bình chọn cao nhất ở trên. Cũng có vô số mã tương tự trong câu hỏi này ). Bạn đang thiếu decodeURIComponentcác chuỗi được trích xuất ít nhất.
Rup

@Rup, cập nhật được thực hiện sau câu trả lời này.
Qwerty

@Qwerty Không phải vậy: bản cập nhật là tháng 2 năm 2013 trong khi câu trả lời này là gần một năm sau vào tháng 2 năm 2014. Nhưng ai quan tâm, có rất nhiều mã tương tự đang bay về. Nhận xét của tôi về giá decodeURIComponentđỡ, mặc dù.
Rup

@Rup Yup, xin lỗi. Và vâng.
Qwerty

2

Điều đáng chú ý, thư viện mà John Slegers đề cập có phụ thuộc jQuery, tuy nhiên đây là một phiên bản là vanilla Javascript.

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

Tôi chỉ đơn giản là bình luận về bài đăng của anh ấy, nhưng tôi không có danh tiếng để làm như vậy. : /

Thí dụ:

Ví dụ dưới đây xử lý chuỗi truy vấn sau, mặc dù không đều,:

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

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

var results = querystring(qs);

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


Thực ra, tôi đã loại bỏ phụ thuộc jQuery trong mã tôi đã trong câu trả lời của tôi ;-)
John Slegers

2

Mật mã

Bài Gist của Eldon McGuinness cho đến nay là cách triển khai hoàn chỉnh nhất của trình phân tích chuỗi truy vấn JavaScript mà tôi đã thấy cho đến nay.

Thật không may, nó được viết dưới dạng một plugin jQuery.

Tôi đã viết lại nó thành vanilla JS và thực hiện một số cải tiến:

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

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

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

Làm thế nào để sử dụng nó

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

Đầu ra

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

Xem thêm Fiddle này .


1

function decode(s) {
    try {
        return decodeURIComponent(s).replace(/\r\n|\r|\n/g, "\r\n");
    } catch (e) {
        return "";
    }
}
function getQueryString(win) {
    var qs = win.location.search;
    var multimap = {};
    if (qs.length > 1) {
        qs = qs.substr(1);
        qs.replace(/([^=&]+)=([^&]*)/g, function(match, hfname, hfvalue) {
            var name = decode(hfname);
            var value = decode(hfvalue);
            if (name.length > 0) {
                if (!multimap.hasOwnProperty(name)) {
                    multimap[name] = [];
                }
                multimap[name].push(value);
            }
        });
    }
    return multimap;
}
var keys = getQueryString(window);
for (var i in keys) {
    if (keys.hasOwnProperty(i)) {
        for (var z = 0; z < keys[i].length; ++z) {
            alert(i + ":" + keys[i][z]);
        }
    }
}

Bạn cũng có thể .toLowerCase () tên nếu bạn muốn đối sánh hfname không phân biệt chữ hoa chữ thường.
Shadow2531

Bạn cũng có thể kiểm tra xem giá trị có trống hay không. Nếu đúng, bạn có thể bỏ qua việc thêm mục nhập để mảng chỉ chứa các giá trị không trống.
Shadow2531

1
unescape () không xử lý các chuỗi UTF-8, vì vậy bạn có thể muốn sử dụng decodeURIComponent (). Tuy nhiên, nếu bạn muốn + ký tự được giải mã thành dấu cách, hãy chạy .replace (/ \ + / g, "") trên chuỗi trước khi giải mã.
Shadow2531

1

Tôi muốn giữ cho nó đơn giản, dễ đọc và nhỏ.

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

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

searchToObject(location.search);

Thí dụ:

searchToObject('?query=myvalue')['query']; // spits out: 'myvalue'

1

Hàm tôi đã viết cho một yêu cầu tương tự như thế này với thao tác chuỗi javascript thuần túy

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

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

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

    return result;
}

Sử dụng:

queryize(window.location.href)['Name'] //returns John
queryize(window.location.href)['Age'] //returns 20
queryize(window.location.href)['Gender'] //returns Male

Gọn gàng, nhưng ngoài cách bạn loại bỏ phần đầu ?có cơ bản giống với hai câu trả lời trên không bạn?
Rup

Chỉ là một cải tiến nhỏ. Cách thức sử dụng phương pháp này giúp người dùng dễ dàng. Người dùng chỉ cần biết giá trị chuỗi truy vấn mà anh ta cần.
Pranavan Maru

1

Nếu bạn đang sử dụng lodash + ES6, đây là một giải pháp đơn giản: _.object(window.location.search.replace(/(^\?)/, '').split('&').map(keyVal => keyVal.split('=')));


0

Được rồi, vì mọi người đang bỏ qua câu hỏi thực sự của tôi, heh, tôi cũng sẽ đăng bài của tôi! Đây là những gì tôi có:

location.querystring = (function() {

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

    var queryStringDictionary = {};

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

    var querystring = unescape(location.search);

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

    if (!querystring) {
        return {};
    }

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

    querystring = querystring.substring(1);

    // '&' seperates key/value pairs

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

    // Load the key/values of the return collection

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

    // Return the key/value pairs concatenated

    queryStringDictionary.toString = function() {

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

        var toString = "?";

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

        return toString;
    };

    // Return the key/value dictionary

    return queryStringDictionary;
})();

Và các bài kiểm tra:

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

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

Bạn nghĩ rằng, JavaScript không phải là tiếng mẹ đẻ của tôi.

Dù sao, tôi đang tìm kiếm một thư viện JavaScript (ví dụ: jQuery, Prototype) đã có một thư viện được viết. :)


1
Tôi không tin rằng bạn thực sự cần một thư viện để thực hiện những gì tương đương với ba dòng mã ở trên! Tuy nhiên, ít nhất bạn sẽ hy vọng một thư viện sẽ ghi nhớ decodeURIComponent () cả khóa và giá trị, điều mà mọi đoạn mã được đăng cho đến nay đều không làm được.
bobince

Bạn không cần thư viện. Tôi muốn so sánh triển khai của mình với một triển khai trong thư viện để tôi có thể xem liệu mình có thiếu bất kỳ trường hợp cạnh nào không. :)
cốt lõi

javascript không phải là tiếng mẹ đẻ của bạn nghĩa là gì, bạn nên học nó ngay cả khi bạn cần một thư viện để sử dụng
Marwan

0

Dựa trên câu trả lời của @CMS Tôi có những điều sau (trong CoffeeScript có thể dễ dàng chuyển đổi sang JavaScript):

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

Bạn có thể dễ dàng lấy những thứ mình cần với:

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

Chiến thắng ở đây là giao diện hướng đối tượng (thay vì chức năng) và nó có thể được thực hiện trên bất kỳ chuỗi nào (không chỉ location.search).

Nếu bạn đang sử dụng thư viện JavaScript, chức năng này đã tồn tại. Ví dụ ở đây là phiên bản của Prototype

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.