Hàm ngược $ .param () trong JavaScript / jQuery


122

Cho mẫu sau:

<form>
    <input name="foo" value="bar">
    <input name="hello" value="hello world">
</form>

Tôi có thể sử dụng $.param( .. )cấu trúc để tuần tự hóa biểu mẫu:

$.param( $('form input') )

=> foo=bar&hello=hello+world

Làm cách nào để giải mã chuỗi trên bằng JavaScript và lấy lại hàm băm?

Ví dụ,

$.magicFunction("foo=bar&hello=hello+world")

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

Tham khảo: jQuery.param( obj ).


2
Này, tôi chỉ thêm nhận xét này để bạn có thể xem cập nhật mà tôi đã thực hiện đối với mã, trong trường hợp bạn đang sử dụng nó ... Tôi đã vô tình viết nó để nó chỉ thay thế đầu tiên +. Bây giờ nó thay thế tất cả chúng!
Blixt

Có các plugin được gọi QueryString. Tôi đã tạo một cái nhưng nó không chấp nhận các tham số, nó chỉ đọc từ window.location.search. Tôi nhớ những người khác chấp nhận các thông số ...
BrunoLM

1
phương pháp refactored jquery BBQ deparam () như NPM module mà không cần phụ thuộc npmjs.com/package/deparam
alexey2baranov

alexey2baranov làm thế nào về việc tái cấu trúc deparam () mà không có NPM là phụ thuộc? :)
Andrew

Câu trả lời:


62

Bạn nên sử dụng hàm deparam của jQuery BBQ . Nó đã được thử nghiệm và ghi lại đầy đủ.


Plugin tuyệt vời! Cám ơn vì đã chia sẻ.
Jonathan

29
Nếu bạn không muốn nhận các plugin toàn BBQ, hàm deparam được chiết xuất như một độc cắm ở đây: github.com/chrissrogers/jquery-deparam
Felipe Castro

2
Thật không may, trang github đã không thấy bất kỳ bản cập nhật nào trong nhiều năm và khi tôi thử nó có vẻ như không tương thích với jQuery mới nhất ... Có vẻ như những gì tôi cần.
pilavdzice

31

Đây là một phiên bản sửa đổi một chút của một hàm mà tôi đã viết cách đây không lâu để làm điều gì đó tương tự.

var QueryStringToHash = function QueryStringToHash  (query) {
  var query_string = {};
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    pair[0] = decodeURIComponent(pair[0]);
    pair[1] = decodeURIComponent(pair[1]);
        // If first entry with this name
    if (typeof query_string[pair[0]] === "undefined") {
      query_string[pair[0]] = pair[1];
        // If second entry with this name
    } else if (typeof query_string[pair[0]] === "string") {
      var arr = [ query_string[pair[0]], pair[1] ];
      query_string[pair[0]] = arr;
        // If third or later entry with this name
    } else {
      query_string[pair[0]].push(pair[1]);
    }
  } 
  return query_string;
};

1
Chính xác những gì tôi nghĩ với câu trả lời được chấp nhận "điều này sẽ không hoạt động với mảng". Giải pháp của bạn hoạt động tốt.
Robert Koritnik

20

Làm thế nào về cách tiếp cận chức năng ngắn này?

function parseParams(str) {
    return str.split('&').reduce(function (params, param) {
        var paramSplit = param.split('=').map(function (value) {
            return decodeURIComponent(value.replace(/\+/g, ' '));
        });
        params[paramSplit[0]] = paramSplit[1];
        return params;
    }, {});
}

Thí dụ:

parseParams("this=is&just=an&example") // Object {this: "is", just: "an", example: undefined}

1
Đây phải là câu trả lời được chấp nhận, không có phụ thuộc bên ngoài.
Michael Robinson

Giải pháp đơn giản, đáng tin cậy và mạnh mẽ. Tôn trọng, thưa ngài.
fmquaglia

5
Đối với những gì nó làm, nó chắc chắn là một giải pháp tốt. Nhưng nó không quan tâm đến mảng hoặc đối tượng được truyền. Url field[][]=a&field[0][]=b&field[0][]=cđược xử lý Object { field[][]: "a", field[0][]: "c" }ở vị trí cần thiết resultobject.field[0] = Array [ "a", "b", "c" ]. Đây là hành vi như mong đợi từ PHP. Giải pháp của @ JackyLi thực hiện điều đó.
ô tô

16

Câu trả lời của tôi:

function(query){
  var setValue = function(root, path, value){
    if(path.length > 1){
      var dir = path.shift();
      if( typeof root[dir] == 'undefined' ){
        root[dir] = path[0] == '' ? [] : {};
      }

      arguments.callee(root[dir], path, value);
    }else{
      if( root instanceof Array ){
        root.push(value);
      }else{
        root[path] = value;
      }
    }
  };
  var nvp = query.split('&');
  var data = {};
  for( var i = 0 ; i < nvp.length ; i++ ){
    var pair = nvp[i].split('=');
    var name = decodeURIComponent(pair[0]);
    var value = decodeURIComponent(pair[1]);

    var path = name.match(/(^[^\[]+)(\[.*\]$)?/);
    var first = path[1];
    if(path[2]){
      //case of 'array[level1]' || 'array[level1][level2]'
      path = path[2].match(/(?=\[(.*)\]$)/)[1].split('][')
    }else{
      //case of 'name'
      path = [];
    }
    path.unshift(first);

    setValue(data, path, value);
  }
  return data;
}

Đúng! Đúng! Đúng! Đây là chính xác mà tôi cần để phân tích cú pháp các tham số đang được gửi bởi JQuery trong một lệnh gọi $ .ajax. Điều này trả về các băm được lồng chính xác. Cảm ơn rất nhiều, Jacky Li!
Pascal Lindelauf

Giải pháp tốt nhất cho đến nay - Nó hoạt động khá tốt! Nhưng khi tôi sử dụng, JSON.stringify(geturlargs('fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc').fld)tôi nhận được {"2":["2"],"3":["4"],"":"cc"}và không phải [null,null,[2],[3,4],"bb","cc"]những gì tôi mong đợi (đây là những gì PHP sẽ mang lại cho tôi).
ô tô

1
Đây là câu trả lời chính xác và vui lòng bỏ qua tất cả các câu trả lời khác, chúng không hoạt động bình thường
Andrew

1
Câu trả lời này là câu trả lời duy nhất giải quyết trường hợp sử dụng cụ thể của tôi (trong đó tôi đã chuyển một đối tượng có khóa / giá trị lồng nhau tới $ .param của jQuery, điều này sẽ hydrat hóa các giá trị đó một cách chính xác khi truy xuất).
delinear

9

Tôi đang sử dụng câu trả lời của David Dorward và nhận ra rằng nó không hoạt động giống như PHP hoặc Ruby on Rails cách họ phân tích cú pháp các tham số:

1) một biến chỉ là một mảng nếu nó kết thúc bằng [], chẳng hạn như ?choice[]=1&choice[]=12, không phải khi nó?a=1&a=2

2) khi tồn tại nhiều tham số có cùng tên, những tham số sau sẽ thay thế những tham số trước đó, như trên máy chủ PHP (Ruby on Rails giữ cái đầu tiên và bỏ qua những cái sau), chẳng hạn như ?a=1&b=2&a=3

Vì vậy, khi sửa đổi phiên bản của David, tôi có:

function QueryStringToHash(query) {

  if (query == '') return null;

  var hash = {};

  var vars = query.split("&");

  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split("=");
    var k = decodeURIComponent(pair[0]);
    var v = decodeURIComponent(pair[1]);

    // If it is the first entry with this name
    if (typeof hash[k] === "undefined") {

      if (k.substr(k.length-2) != '[]')  // not end with []. cannot use negative index as IE doesn't understand it
        hash[k] = v;
      else
        hash[k.substr(0, k.length-2)] = [v];

    // If subsequent entry with this name and not array
    } else if (typeof hash[k] === "string") {
      hash[k] = v;  // replace it

    // If subsequent entry with this name and is array
    } else {
      hash[k.substr(0, k.length-2)].push(v);
    }
  } 
  return hash;
};

được kiểm tra khá kỹ lưỡng.


Đặc điểm của uri là? A = 1 & a = 2 phải là một mảng. Ruby on Rails và PHP không tuân theo đặc điểm kỹ thuật thực tế.
adiktofsugar

Điểm mấu nơi bạn thêm vào mảng nên hash[k.substr(0, k.length-2)] = [v];hash[k.substr(0, k.length-2)].push(v);
Baptiste Pernet

Sẽ rất tốt nếu điều này có thể được cung cấp thông qua npm
Erik van Velzen

7

Tôi biết đây là một chủ đề cũ, nhưng có lẽ vẫn còn một số liên quan trong đó?

Lấy cảm hứng từ giải pháp tốt của Jacky Li, tôi đã thử một biến thể nhỏ của riêng mình với vật kính để có thể quan tâm đến các kết hợp tùy ý của các mảng và đối tượng làm đầu vào. Tôi đã xem xét cách PHP sẽ làm điều đó và cố gắng làm cho một cái gì đó "tương tự" diễn ra. Đây là mã của tôi:

function getargs(str){
   var ret={};
   function build(urlnam,urlval,obj){ // extend the return object ...
    var i,k,o=obj, x, rx=/\[([^\]]*)\]/g, idx=[urlnam.replace(rx,'')];
    while (x=rx.exec(urlnam)) idx.push(x[1]); 
    while(true){
     k=idx.shift();
     if(k.trim()=='') {// key is empty: autoincremented index
       if (o.constructor.name=='Array') k=o.length; // for Array
       else if (o===obj ) {k=null}  // for first level property name
       else {k=-1;                                  // for Object
         for(i in o) if (+i>k) k=+i;
         k++;
       }
     }
     if(idx.length) { 
       // set up an array if the next key (idx[0]) appears to be
       // numeric or empty, otherwise set up an object:
       if (o[k]==null || typeof o[k]!='object') o[k]=isNaN(idx[0])?{}:[]; 
       o=o[k]; // move on to the next level
     }
     else { // OK, time to store the urlval in its chosen place ...
       // console.log('key',k,'val',urlval);                 
       o[k]=urlval===""?null:urlval; break; // ... and leave the while loop.
     } 
    }
    return obj;
   }
   // ncnvt: is a flag that governs the conversion of
   // numeric strings into numbers
   var ncnvt=true,i,k,p,v,argarr=[],
       ar=(str||window.location.search.substring(1)).split("&"),
       l=ar.length;
   for (i=0;i<l;i++) {if (ar[i]==="") continue;
     p=ar[i].split("=");k=decodeURIComponent(p[0]);
     v=p[1];v=(v!=null)?decodeURIComponent(v.replace(/\+/g,'%20')):'';
     if (ncnvt && v.trim()>"" && !isNaN(v)) v-=0;
     argarr.push([k,v]);  // array: key-value-pairs of all arguments
   }
   for (i=0,l=argarr.length;i<l;i++) build(argarr[i][0],argarr[i][1],ret);
   return ret;
}

Nếu hàm được gọi mà không có str-argument, nó sẽ được coi window.location.search.slice(1)là đầu vào.

Vài ví dụ:

['a=1&a=2',                               // 1
 'x[y][0][z][]=1',                        // 2
 'hello=[%22world%22]&world=hello',       // 3
 'a=1&a=2&&b&c=3&d=&=e&',                 // 4
 'fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc',  // 5
 $.param({a:[[1,2],[3,4],{aa:'one',bb:'two'},[5,6]]}), // 6
 'a[]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13',// 7
 'a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13'// 8
].map(function(v){return JSON.stringify(getargs(v));}).join('\n')

kết quả trong

{"a":2}                                    // 1
{"x":{"y":[{"z":[1]}]}}                    // 2
{"hello":"[\"world\"]","world":"hello"}    // 3
{"a":2,"b":null,"c":3,"d":null,"null":"e"} // 4 = { a: 2, b: null, c: 3, d: null, null: "e" }
{"fld":[null,null,[2],[3,4],"bb","cc"]}    // 5 
{"a":[[1,2],[3,4],{"aa":"one","bb":"two"},[5,6]]}  // 6
{"a":["hi",2,null,[7,99],13]}              // 7
{"a":{"0":2,"3":[7,99],"4":13,"x":"hi"}}   // 8

Trong khi giải pháp của Jacky Li sẽ tạo ra hộp đựng bên ngoài anhư một vật thể đơn giản

{a:{"0":["1","2"],"1":["3","4"],"2":["5","6"]}} // 6: JackyLi's output

getargs() nhìn vào chỉ mục đã cho đầu tiên cho bất kỳ mức nào để xác định xem mức này sẽ là một đối tượng (chỉ số không phải số) hay một mảng (số hoặc trống), do đó dẫn đến kết quả như được hiển thị trong bove danh sách (số 6).

Nếu đối tượng hiện tại là một mảng thì nulls được chèn vào bất cứ nơi nào cần thiết để biểu diễn các vị trí trống. Mảng luôn được đánh số liên tục và dựa trên 0).

Lưu ý rằng trong ví dụ không có. 8 "autoincrement" cho các chỉ số trống vẫn hoạt động, ngay cả khi chúng ta đang xử lý một đối tượng chứ không phải một mảng.

Theo như tôi đã thử nghiệm, getargs()hành vi của tôi khá giống với $.deparam() plugin jQuery tuyệt vời của Chriss Roger được đề cập trong câu trả lời được chấp nhận. Sự khác biệt chính là getargschạy mà không có jQuery và nó tự động tăng các đối tượng trong khi $.deparam()sẽ không làm điều đó:

JSON.stringify($.deparam('a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13').a);

kết quả trong

{"3":["7","99"],"x":"hi","undefined":"13"}

Trong $.deparam()chỉ mục []được hiểu là một undefinedthay vì một chỉ mục số tự động tăng.


cảm ơn vì chức năng tuyệt vời này. Tuy nhiên, tôi nhận thấy rằng nếu bạn sử dụng số làm khóa trong mảng, ví dụ như '? A [5] [] = x' thì khóa được sử dụng làm số khi tạo đối tượng và do đó nó tạo ra 5 phần tử trống trong trường hợp của tôi. Nó phải coi khóa số là chuỗi và do đó tạo đối tượng với "5" (có dấu ngoặc kép) làm khóa và x là giá trị. Tôi có thể buộc url phải là '? A ["5"] [] = x' nhưng điều này thật xấu ...
Andrew

@Andrew: Đây là một quyết định thiết kế có chủ ý từ phía tôi: Theo như tôi nhớ, giải pháp của Jack sẽ hoạt động tốt hơn theo cách bạn mong đợi. Tôi đã giới thiệu dòng o[k]=isNaN(idx[0])?{}:[];với mục đích tạo một mảng, bất cứ khi nào tôi gặp một chỉ mục số là chỉ mục đầu tiên được cung cấp cho một đối tượng mới. Nếu không, tôi sẽ tạo một đối tượng chung chung. Bạn có thể sửa đổi phần đó của mã để phù hợp hơn với nhu cầu của mình. I E. một cái gì đó như o[k]={}nên làm thủ thuật.
ô tô 10 phút,

cảm ơn. PS, bạn chắc chắn nên xóa console.log ở giữa chức năng của mình;)
Andrew

@Andrew: Cảm ơn, chỉ cần nhận xét nó ra. Chắc đã bỏ qua nó khi tôi đăng mã.
ô tô 10 phút,

6

Đây là cách bạn có thể tạo một hàm jQuery mới:

jQuery.unparam = function (value) {
    var
    // Object that holds names => values.
    params = {},
    // Get query string pieces (separated by &)
    pieces = value.split('&'),
    // Temporary variables used in loop.
    pair, i, l;

    // Loop through query string pieces and assign params.
    for (i = 0, l = pieces.length; i < l; i++) {
        pair = pieces[i].split('=', 2);
        // Repeated parameters with the same name are overwritten. Parameters
        // with no value get set to boolean true.
        params[decodeURIComponent(pair[0])] = (pair.length == 2 ?
            decodeURIComponent(pair[1].replace(/\+/g, ' ')) : true);
    }

    return params;
};

4
Tôi không thích chức năng này. Tại sao tham số không có giá trị phải nhận giá trị là 'true'? Tại sao không null? Tôi nghĩ rằng quyết định thiết kế này có thể dẫn đến những lỗi rất nhỏ. Ngoài ra, tại sao không xử lý tình huống trong đó tham số có thể có nhiều giá trị thay vì chọn giá trị 'cuối cùng'? Giải pháp được đăng bởi David là tốt hơn nhiều.
SolutionYogi,

4
Nó là trueđể người ta có thể kiểm tra if (params.redirect)hoặc tương tự. Nếu bạn muốn khác biệt giữa truevà giá trị khác, bạn sẽ sử dụng if (params.redirect === true). Một nullgiá trị sẽ không giúp ích gì theo bất kỳ cách nào mà tôi có thể nghĩ ra. Lý do tôi không làm như David là vì tôi coi trọng tính nhất quán hơn là tính linh hoạt. Với phương pháp của anh ấy, tôi phải kiểm tra xem giá trị là một chuỗi hay một mảng để sử dụng giá trị của nó. Theo ý kiến ​​của tôi, nó phải luôn là một chuỗi ( truegiá trị chuyển đổi 'true'mà tôi nghĩ là ổn), hoặc luôn luôn là một mảng. Tôi đã chọn chuỗi.
Blixt

Theo tài khoản đó, nếu nó là params.delete, nó sẽ được đặt thành true và tôi sẽ làm điều gì đó có hại. Như bạn có thể thấy, việc đưa ra ví dụ rất dễ dàng. 'null' chỉ định rõ ràng rằng không có giá trị nào tồn tại và quyết định được để cho người gọi xem họ muốn diễn giải nó như thế nào. Về nhiều giá trị, hãy xem nó theo cách này. Bằng cách ăn hết, bạn đảm bảo rằng một trong hai người gọi sẽ dành thời gian gỡ lỗi tại sao anh ta chỉ nhận được một giá trị HOẶC sau này hãy đến và sửa đổi mã. Bằng cách trả trước mảng, người gọi sẽ ngay lập tức biết cách xử lý chúng. Hủy bỏ thông tin không bao giờ là tốt, IMHO.
SolutionYogi

2
Nếu URL là /abc?deletethì tôi mong đợi sẽ có một mục nhập cho delete. Tôi không thấy điều đó khác nhau như thế nào? Tôi thậm chí không thấy làm thế nào bạn có thể thích mã khác vì lý do này, bởi vì mã đó sẽ đặt giá trị thành chuỗi 'undefined'không tốt hơn. Và đối với nhiều giá trị, đó là một trường hợp đơn giản và linh hoạt. Tôi hiếm khi thấy việc sử dụng nhiều giá trị trong các chuỗi truy vấn, nhưng nếu bạn muốn chúng, hãy luôn trả về một mảng có hơn 1 giá trị. Không bao giờ trộn lẫn kiểu trả về; thì bạn sẽ phải dành thời gian để gỡ lỗi vì những gì thường là một chuỗi đột nhiên có thể là một mảng.
Blixt

Cảm ơn. Tôi không nghĩ rằng có một viên đạn bạc. Tôi đã lấy mã của bạn và sửa đổi nó một chút, loại bỏ các giá trị boolean, thêm phân tích cú pháp các tham số mảng. ? foo [] = 1 & foo [] = 2 => foo: [ "1", "2"]
SEB

6

Cảm ơn anh ấy http://james.padolsey.com/javascript/parsing-urls-with-the-dom/

Khá dễ dàng: D

function params_unserialize(p){
var ret = {},
    seg = p.replace(/^\?/,'').split('&'),
    len = seg.length, i = 0, s;
for (;i<len;i++) {
    if (!seg[i]) { continue; }
    s = seg[i].split('=');
    ret[s[0]] = s[1];
}
return ret;}

2
Điều này không hoạt động với các hộp chọn có nhiều tùy chọn, bởi vì nó chỉ giữ được chọn cuối cùng.
Fernando Fabreti

Xin lỗi nhưng tôi không thể hiểu điểm bạn đang đề cập trong nhận xét là gì. Chức năng được tham chiếu ở đây là hủy chuẩn hóa / phân tích cú pháp một URI với các tham số như ?something=1&param2=value2thành một mảng. Ý bạn là gì với "không hoạt động với các hộp chọn có nhiều tùy chọn"?
brituscat

4

Đây là cách triển khai JavaScript của tôi mà tôi sử dụng trong trang JScript ASP Classic phía máy chủ ( bản trình diễn ):

// Transforms a query string in the form x[y][0][z][]=1 into {x:{y:[{z:[1]}]}}
function parseJQueryParams(p) {
    var params = {};
    var pairs = p.split('&');
    for (var i=0; i<pairs.length; i++) {
        var pair = pairs[i].split('=');
        var indices = [];
        var name = decodeURIComponent(pair[0]),
            value = decodeURIComponent(pair[1]);

        var name = name.replace(/\[([^\]]*)\]/g, 
            function(k, idx) { indices.push(idx); return ""; });

        indices.unshift(name);
        var o = params;

        for (var j=0; j<indices.length-1; j++) {
            var idx = indices[j];
            var nextIdx = indices[j+1];
            if (!o[idx]) {
                if ((nextIdx == "") || (/^[0-9]+$/.test(nextIdx)))
                    o[idx] = [];
                else
                    o[idx] = {};
            }
            o = o[idx];
        }

        idx = indices[indices.length-1];
        if (idx == "") {
            o.push(value);
        }
        else {
            o[idx] = value;
        }
    }
    return params;
}

Cho đến nay điều tốt nhất tôi tìm thấy cho các mảng lồng nhau
ymakux

3

dùng cái này :

// convert query string to json object
var queryString = "cat=3&sort=1&page=1";

queryString
    .split("&")
    .forEach((item) => {
        const prop = item.split("=");
        filter[prop[0]] = prop[1];
    });

console.log(queryString);

1

Tôi đã đưa ra giải pháp này, hoạt động giống như hàm .Net HttpUtility.ParseQueryString.

Kết quả là, các tham số chuỗi truy vấn được lưu trữ trong các thuộc tính dưới dạng danh sách các giá trị, do đó, điều đó qsObj["param"]sẽ giống như gọi GetValues("param")trong .Net.

Tôi hy vọng bạn thích nó. JQuery không bắt buộc.

var parseQueryString = function (querystring) {
    var qsObj = new Object();
    if (querystring) {
        var parts = querystring.replace(/\?/, "").split("&");
        var up = function (k, v) {
            var a = qsObj[k];
            if (typeof a == "undefined") {
                qsObj[k] = [v];
            }
            else if (a instanceof Array) {
                a.push(v);
            }
        };
        for (var i in parts) {
            var part = parts[i];
            var kv = part.split('=');
            if (kv.length == 1) {
                var v = decodeURIComponent(kv[0] || "");
                up(null, v);
            }
            else if (kv.length > 1) {
                var k = decodeURIComponent(kv[0] || "");
                var v = decodeURIComponent(kv[1] || "");
                up(k, v);
            }
        }
    }
    return qsObj;
};

Đây là cách sử dụng nó:

var qsObj = parseQueryString("a=1&a=2&&b&c=3&d=&=e&");

Để xem trước kết quả trong bảng điều khiển juste, hãy nhập:

JSON.stringify(qsObj)

Đầu ra:

"{"a":["1","2"],"null":["","b",""],"c":["3"],"d":[""],"":["e"]}"

1

Có một đoạn lót tuyệt đẹp tại CSS-Tricks (nguồn gốc từ Nicholas Ortenzio ):

function getQueryParameters(str) {
    return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
}

Phần thực sự thông minh là cách nó sử dụng thisđối tượng của hàm ẩn danh , thêm một cặp khóa / giá trị cho mỗi truy vấn trong chuỗi. Điều đó nói rằng, có một số chỗ để cải thiện. Tôi đã sửa đổi nó một chút bên dưới, với những thay đổi sau:

  1. Đã thêm xử lý các chuỗi trống và đầu vào không phải chuỗi.

  2. Xử lý các chuỗi được mã hóa URI ( %40-> @, v.v.).

  3. Đã xóa việc sử dụng mặc định document.location.searchkhi đầu vào trống.

  4. Đã thay đổi tên, làm cho nó dễ đọc hơn, thêm nhận xét.

function deparam(str) {
    // Uses an empty 'this' to build up the results internally
    function splitQuery(query) {
        query = query.split('=').map(decodeURIComponent);
        this[query[0]] = query[1];
        return this;
    }

    // Catch bad input
    if (!str || !(typeof str === 'string' || str instanceof String))
        return {};

    // Split the string, run splitQuery on each piece, and return 'this'
    var queries = str.replace(/(^\?)/,'').split('&');
    return queries.map(splitQuery.bind({}))[0];
}

1

Đây thực sự là một câu hỏi cũ, nhưng khi tôi sắp nói - những người khác có thể đến với bài đăng này và tôi muốn làm mới chủ đề này một chút. Ngày nay không cần phải thực hiện các giải pháp tùy chỉnh - đã có giao diện 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);
}

Hạn chế duy nhất mà tôi biết - tính năng này không được hỗ trợ trong IE / Edge.


Rất tiếc là IE không hỗ trợ, như thường lệ, trong trường hợp bạn cần hỗ trợ trình duyệt này.
Lauren

0

Đây là phiên bản của tôi trong Coffeescript. Cũng hoạt động cho url như http://localhost:4567/index.html?hello=[%22world%22]&world=hello#/home

getQueryString: (url)->
    return null if typeof url isnt 'string' or url.indexOf("http") is -1

    split = url.split "?"

    return null if split.length < 2 
    path = split[1]

    hash_pos = path.indexOf "#"
    path = path[0...hash_pos] if hash_pos isnt -1

    data = path.split "&"
    ret = {}
    for d in data
      [name, val] = d.split "=" 
      name = decodeURIComponent name
      val = decodeURIComponent val
      try 
        ret[name] = JSON.parse val
      catch error
        ret[name] = val
    return ret

0

Đây là một đơn giản và nhỏ gọn nếu bạn chỉ muốn nhanh chóng nhận được các tham số từ một yêu cầu GET:

function httpGet() {
    var a={},b,i,q=location.search.replace(/^\?/,"").split(/\&/);
    for(i in q) if(q[i]) {b=q[i].split("=");if(b[0]) a[b[0]]=
    decodeURIComponent(b[1]).replace(/\+/g," ");} return a;
}

Nó chuyển đổi

something?aa=1&bb=2&cc=3

thành một đối tượng như

{aa:1,bb:2,cc:3}

0

Tạo một biểu diễn được tuần tự hóa của một mảng hoặc đối tượng (có thể được sử dụng làm chuỗi truy vấn URL cho các yêu cầu AJAX).

<button id='param'>GET</button> 
<div id="show"></div>
<script>
  $('#param').click(function () {
    var personObj = new Object();
    personObj.firstname = "vishal"
    personObj.lastname = "pambhar";
    document.getElementById('show').innerHTML=$.param(`personObj`));
  });
</script>
output:firstname=vishal&lastname=pambhar

1
Mã không có giải thích không được hoan nghênh. Có thể vui lòng tiếp tục và giải thích mã của bạn?
L. Guthardt

Tạo ra một đại diện serialize của một mảng hoặc đối tượng (có thể được sử dụng như là chuỗi truy vấn URL cho các yêu cầu AJAX)
Vishal Patel

Vui lòng thêm lời giải thích trực tiếp trong câu trả lời của bạn, bằng cách chỉnh sửa nó. Không có trong bình luận mặc dù.
L. Guthardt

-1

câu trả lời có thể sử dụng một chút sang trọng của jQuery :

(function($) {
var re = /([^&=]+)=?([^&]*)/g;
var decodeRE = /\+/g; // Regex for replacing addition symbol with a space
var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );};
$.parseParams = function(query) {
    var params = {}, e;
    while ( e = re.exec(query) ) {
        var k = decode( e[1] ), v = decode( e[2] );
        if (k.substring(k.length - 2) === '[]') {
            k = k.substring(0, k.length - 2);
            (params[k] || (params[k] = [])).push(v);
        }
        else params[k] = v;
    }
    return params;
};
})(jQuery);

fork tại https://gist.github.com/956897


-1

Bạn có thể sử dụng chức năng .serializeArray()( Liên kết ) của chính jQuery. Hàm này trả về một mảng cặp khóa-giá trị. Ví dụ kết quả:

[
  { name: "id", value: "1" },
  { name: "version", value: "100" }
]

1
Đây không phải là những gì đã được hỏi. Anh ta muốn biến một chuỗi thành một hàm băm. serializeArray có một biểu mẫu và trả về một mảng.
Daniel Bang
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.