Mã hóa chuỗi truy vấn của Đối tượng Javascript


481

Bạn có biết một cách nhanh chóng và đơn giản để mã hóa Đối tượng Javascript thành một đối tượng stringmà tôi có thể chuyển quaGET Yêu cầu không?

Không jQuery, không có khung nào khác - chỉ là Javascript đơn giản :)


Tại sao JQuery không thể là một giải pháp nếu có một giải pháp phù hợp cho giải pháp của bạn?
Eaglei22

@ Eaglei22 bởi vì tại thời điểm đó tôi đang làm việc trong một dự án cho một thiết bị hộp hàng đầu IPTV và không có thư viện bên ngoài nào được phép. ;-)
napolux

1
Cảm ơn vì sự trả lời. Thỉnh thoảng tôi thấy đặc điểm kỹ thuật này và luôn tự hỏi một kịch bản tại sao. Vâng, bây giờ tôi có một, cảm ơn! :)
Eaglei22

9
@ Eaglei22 Bởi vì đôi khi bạn không muốn tải một thư viện lớn để lấy một phần tử theo id.
Aaron Harun

hầu hết các trình duyệt đều hỗ trợ URLSearchParamsngay bây giờ ...
mb21

Câu trả lời:


810

như thế này?

serialize = function(obj) {
  var str = [];
  for (var p in obj)
    if (obj.hasOwnProperty(p)) {
      str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
    }
  return str.join("&");
}

console.log(serialize({
  foo: "hi there",
  bar: "100%"
}));
// foo=hi%20there&bar=100%25

Chỉnh sửa: cái này cũng chuyển đổi các đối tượng đệ quy (sử dụng ký hiệu "mảng" php cho chuỗi truy vấn)

serialize = function(obj, prefix) {
  var str = [],
    p;
  for (p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p,
        v = obj[p];
      str.push((v !== null && typeof v === "object") ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
}

console.log(serialize({
  foo: "hi there",
  bar: {
    blah: 123,
    quux: [1, 2, 3]
  }
}));
// foo=hi%20there&bar%5Bblah%5D=123&bar%5Bquux%5D%5B0%5D=1&bar%5Bquux%5D%5B1%5D=2&bar%5Bquux%5D%5B2%5D=3


2
Sẽ không phá vỡ được {foo: [1,2,3], thanh: "100%"}?
Quentin

1
@Ofri: Đối với các yêu cầu POST đến một máy chủ được thiết lập để nhận nó, JSON là một lựa chọn tốt. Đối với các yêu cầu GET, nếu bạn gửi bất kỳ thứ gì ngoài một vài tham số đơn giản đến máy chủ thì có khả năng thiết kế của bạn đã sai.
Tim Xuống

2
@Marcel Đó là vì chức năng không kiểm tra hasOwnProperty. Tôi đã cập nhật fiddle của bạn để bây giờ nó hiện: jsfiddle.net/rudiedirkx/U5Tyb/1
Rudie

1
@TimDown Về nhận xét của bạn gửi các tham số đơn giản trong các yêu cầu GET. Tôi không đồng ý. Việc nhóm các tham số thành các mảng có thể trở nên tiện dụng khi PHP ở phía máy chủ tìm thấy một mảng kết hợp sẵn sàng ổn định. Tôi không thể thấy tại sao điều này là sai khi thiết kế.
Savas Vedova

1
Là 'if (obj.hasOwnProperty (prop))' có cần thiết không? Vòng lặp for in chỉ qua các thuộc tính của đối tượng để gọi hasOwnProperty luôn luôn đánh giá là đúng
Arnon

231

jQuery có một chức năng cho việc này, jQuery.param()nếu bạn đã sử dụng nó, bạn có thể sử dụng chức năng đó: http://api.jquery.com/jquery.param/

thí dụ:

var params = { width:1680, height:1050 };
var str = jQuery.param( params );

str bây giờ có chứa width=1680&height=1050


119
trích dẫn Napolux (OP): "chỉ đơn giản là Javascript" . : P
Sk8erPeter

6
jQuery.param () có hành vi độc ác. Cố gắng thực hiện var a = []; một [2564] = 12; console.log (jQuery.param ({propertylist: a})); để xem những gì tôi có ý nghĩa.
akond

13
@akond Tài liệu jQuery đặc biệt nói rằng bạn không thể vượt qua trong một mảng trống.
Ariel

4
@Ariel Anh ấy không đi trong một mảng trần. Anh ta đi qua một mảng chỉ có một giá trị tại chỉ mục 2564. Để chứng minh: var a = []; a[5] = 'foo'; jQuery.param({ parameters: a }); Kết quả "parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=foo". Mà, trong khi chính xác, có thể không phải là những gì bạn mong đợi.
Hội trường Chris

4
Câu hỏi đã hỏi cụ thể Vanilla JS
Bug Hunter 219

190

Chỉ cần sử dụng URLSearchParamsĐiều này hoạt động trong tất cả các trình duyệt hiện tại

new URLSearchParams(object).toString()

5
Không, vì nó không làm các đối tượng đệ quy
Eddie Monge Jr

Không hoạt động trên đối tượng lồng nhau. let j = { m: 5, n: { k: 1 } }; new URLSearchParams(j).toString(); // result "m=5&n=%5Bobject+Object%5D"
cấu trúc hitautodest

19
@EddieMridJr Chuỗi truy vấn là các cặp khóa-giá trị theo thiết kế, bạn thậm chí không muốn tuần tự hóa các đối tượng lồng nhau Câu trả lời này là cách hiện đại để đi. Upvote cần thiết.
Romain Durand

5
Đúng, chúng là các cặp giá trị chính nhưng không có gì nói rằng giá trị không thể là một đối tượng được mã hóa chuỗi. Ngoài ra, các câu hỏi ban đầu yêu cầu "Đối tượng Javascript thành một chuỗi", có thể có các thuộc tính lồng nhau
Eddie Monge Jr

@EddieMridJr ngay cả câu trả lời được chấp nhận (và những câu trả lời khác sau một cái nhìn ngắn gọn) không hỗ trợ đối tượng lồng nhau. Bạn có thể stringifycác đối tượng lồng nhau trước khi bạn có thểURLSearchParams
Mosh Feu

128
Object.keys(obj).reduce(function(a,k){a.push(k+'='+encodeURIComponent(obj[k]));return a},[]).join('&')

Chỉnh sửa: Tôi thích phần lót này, nhưng tôi cá rằng nó sẽ là một câu trả lời phổ biến hơn nếu nó phù hợp với câu trả lời được chấp nhận về mặt ngữ nghĩa:

function serialize( obj ) {
    let str = '?' + Object.keys(obj).reduce(function(a, k){
        a.push(k + '=' + encodeURIComponent(obj[k]));
        return a;
    }, []).join('&');
    return str;
}

1
Một dòng dành riêng cho chức năng khử sẽ cải thiện đáng kể khả năng đọc.
Aurelien Ribon

54
Sử dụng .map () thay vì .reduce () thậm chí còn đơn giản hơn: Object.keys(obj).map(k => k + '=' + encodeURIComponent(obj[k])).join('&')
Jannes

2
Chỉ cần lưu ý rằng Object.keyschỉ có sẵn trong IE> = 9
Johnston

5
Mã @Jannes được cải thiện hơn nữa bằng cách sử dụng các mẫu ES6 thay vì ghép nối -Object.keys(obj).map(k => `${k}=${encodeURIComponent(obj[k])}`).join('&')
csilk

1
Trong trường hợp các khóa của bạn cần encodeUriComponent: Object.entries(obj).map(e => e.map(ee => encodeURIComponent(ee)).join('=')).join('&');
Blaise

112

Đây là một lớp lót trong ES6:

Object.keys(obj).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`).join('&');

thay thế khóa w / k và bạn là vàng
Jamie Kudla

17
Cảnh báo! Điều này chỉ hoạt động trên các đối tượng nông. Nếu bạn có một thuộc tính cấp cao nhất là một đối tượng khác, thì một lớp lót này sẽ xuất ra "key =% 5Bobject% 20Object% 5D". Chỉ là một cái đầu lên.
Andrew Allbright

4
Ngoài ra, điều này không nhổ mảng. Tôi đã nhận được export?actions[]=finance,create,editkhi nó cần phải export?actions[]=finance&actions[]=create&actions[]=editlà tiêu chuẩn khủng khiếp.
darkbluesun

3
Mảng gần như luôn luôn là "bạn là của riêng bạn" bởi vì các đối số URL chỉ là các chuỗi liên quan đến thông số kỹ thuật, do đó, bạn có thể tạo ra bất cứ thứ gì không phải là một chuỗi được máy chủ đọc chính xác bạn đang gọi actions[]là ký hiệu PHP; Django sử dụng nhiều actionthay thế (không có []hậu tố); một số ORM / CMS khác yêu cầu danh sách được phân tách bằng dấu phẩy, v.v. Vì vậy, "nếu đó không phải là chuỗi đơn giản, trước tiên hãy đảm bảo bạn biết máy chủ của mình muốn gì".
Mike 'Pomax' Kamermans

Giải pháp rất thanh lịch!
Anh Trần

51

Với Node.js v6.6.3

const querystring = require('querystring')

const obj = {
  foo: 'bar',
  baz: 'tor'
}

let result = querystring.stringify(obj)
// foo=bar&baz=tor

Tham khảo: https://nodejs.org/api/queryopes.html


8
Điều này không nên được đánh giá thấp IMO, nếu đó là JS trên máy chủ thì đây sẽ là câu trả lời chính xác.
Michael

4
Có vẻ như nó không hỗ trợ các đối tượng lồng nhau.
Vàng Yarin

43

Tôi đề nghị sử dụng URLSearchParamsgiao diện:

const searchParams = new URLSearchParams();
const search = {foo: "hi there", bar: "100%" };
Object.keys(search).forEach(key => searchParams.append(key, search[key]));
console.log(searchParams.toString())

Hoặc bằng cách chuyển đối tượng tìm kiếm vào hàm tạo như thế này:

const obj = {foo: "hi there", bar: "100%" };
const params = new URLSearchParams(obj).toString();

1
Đề xuất thú vị, nhưng lưu ý rằng trình duyệt hỗ trợ cho tính năng này vẫn còn rất chắp vá.
mrec

Nếu bạn sẽ không hỗ trợ IE (hiện khá phổ biến) và một số phiên bản di động cụ thể, thì đây là câu trả lời tốt nhất, vì đây là JavaScript đơn giản.
Marcos Sandrini

24

Một sửa đổi nhỏ cho giải pháp được chấp nhận bởi user187291:

serialize = function(obj) {
   var str = [];
   for(var p in obj){
       if (obj.hasOwnProperty(p)) {
           str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
       }
   }
   return str.join("&");
}

Việc kiểm tra hasOwnProperty trên đối tượng làm cho JSLint / JSHint hài lòng và nó ngăn chặn việc vô tình tuần tự hóa các phương thức của đối tượng hoặc các công cụ khác nếu đối tượng là bất cứ thứ gì ngoại trừ một từ điển đơn giản. Xem đoạn trên cho các tuyên bố trong trang này: http://javascript.crockford.com/code.html


14

Chà, mọi người dường như đặt chiếc áo lót của anh ấy ở đây để tôi đi đây:

const encoded = Object.entries(obj).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&");

1
Object.entries không được hỗ trợ trong IE.
MBouwman

@MBouwman tất nhiên, IE bị phá vỡ tốt và xấu, đó là lý do tại sao bạn phải sử dụng babel / core-js
chpio

@chpio Babel / core-js không hỗ trợ Object.entries nếu tôi đúng.
MBouwman

core có hỗ trợ cho Object.entries: github.com/zloirock/core-js/blob/master/ và thậm chí biến đổi thời gian chạy babel corejs2 cũ cũng hỗ trợ nó cũng như github.com/babel/babel/blob/
tựa

12

Bạn có cần gửi các đối tượng tùy ý? Nếu vậy, GET là một ý tưởng tồi vì có giới hạn về độ dài của URL mà tác nhân người dùng và máy chủ web sẽ chấp nhận. Đề xuất của tôi sẽ là xây dựng một loạt các cặp giá trị tên để gửi và sau đó xây dựng một chuỗi truy vấn:

function QueryStringBuilder() {
    var nameValues = [];

    this.add = function(name, value) {
        nameValues.push( {name: name, value: value} );
    };

    this.toQueryString = function() {
        var segments = [], nameValue;
        for (var i = 0, len = nameValues.length; i < len; i++) {
            nameValue = nameValues[i];
            segments[i] = encodeURIComponent(nameValue.name) + "=" + encodeURIComponent(nameValue.value);
        }
        return segments.join("&");
    };
}

var qsb = new QueryStringBuilder();
qsb.add("veg", "cabbage");
qsb.add("vegCount", "5");

alert( qsb.toQueryString() );

11

Trình tạo truy vấn kiểu Rails / PHP

Phương pháp này chuyển đổi một đối tượng Javascript thành một URI Query String. Cũng xử lý các mảng và các đối tượng lồng nhau (trong Rails/ PHPcú pháp):

function serializeQuery(params, prefix) {
  const query = Object.keys(params).map((key) => {
    const value  = params[key];

    if (params.constructor === Array)
      key = `${prefix}[]`;
    else if (params.constructor === Object)
      key = (prefix ? `${prefix}[${key}]` : key);

    if (typeof value === 'object')
      return serializeQuery(value, key);
    else
      return `${key}=${encodeURIComponent(value)}`;
  });

  return [].concat.apply([], query).join('&');
}

Cách sử dụng ví dụ:

let params = {
  a: 100,
  b: 'has spaces',
  c: [1, 2, 3],
  d: { x: 9, y: 8}
}

serializeQuery(params)
// returns 'a=100&b=has%20spaces&c[]=1&c[]=2&c[]=3&d[x]=9&d[y]=8

Ví dụ tốt đẹp. Tôi đã sửa một lỗi đánh máy trong câu trả lời của bạn. Nhân tiện, sẽ rất thú vị nếu bạn chỉnh sửa functionđể loại trừ falsycác giá trị (null, không xác định, NaN, '') ...
developer033

8

sử dụng JSON.

hãy xem câu hỏi này để biết ý tưởng về cách thực hiện.


2
Tôi không biết anh ấy viết máy chủ bằng gì, nhưng hầu hết các ngôn ngữ hiện đại đều có các gói tốt đọc JSON. Bên cạnh đó, ngay cả khi anh ta kết thúc việc triển khai nó, tốt hơn là triển khai mã máy chủ đọc JSON hơn là phát minh ra một sơ đồ mã hóa mới của riêng bạn. Các mã hóa DIY như thế này có xu hướng bị lỗi (vì bạn thường không nghĩ về tất cả các trường hợp có thể xảy ra, như giá trị là một mảng trong chính nó, v.v.).
Ofri Raviv

Về cơ bản, bạn có đề xuất chuyển đổi đối tượng teh thành JSON và sau đó chuyển toàn bộ chuỗi JSON đến máy chủ dưới dạng một tham số truy vấn GET không?
Marco Demaio

8

Đây là phiên bản cà phê của câu trả lời được chấp nhận. Điều này có thể tiết kiệm thời gian cho một ai đó.

serialize = (obj, prefix) ->
  str = []
  for p, v of obj
    k = if prefix then prefix + "[" + p + "]" else p
    if typeof v == "object"
      str.push(serialize(v, k))
    else
      str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v))

  str.join("&")

Cảm ơn alfonso! Thực sự tiết kiệm thời gian của tôi!
Lukas

6

Đây là phiên bản ngắn gọn và đệ quy với Object.entries . Nó xử lý các mảng lồng nhau tùy ý, nhưng các đối tượng không lồng nhau. Nó cũng loại bỏ các yếu tố trống:

const format = (k,v) => v !== null ? `${k}=${encodeURIComponent(v)}` : ''

const to_qs = (obj) => {
    return [].concat(...Object.entries(obj)
                       .map(([k,v]) => Array.isArray(v) 
                          ? v.map(arr => to_qs({[k]:arr})) 
                          : format(k,v)))
           .filter(x => x)
           .join('&');
}

Ví dụ:

let json = { 
    a: [1, 2, 3],
    b: [],              // omit b
    c: 1,
    d: "test&encoding", // uriencode
    e: [[4,5],[6,7]],   // flatten this
    f: null,            // omit nulls
    g: 0
};

let qs = to_qs(json)

=> "a=1&a=2&a=3&c=1&d=test%26encoding&e=4&e=5&e=6&e=7&g=0"

Phiên bản này đã làm công việc cho tôi khi xử lý các mảng lồng nhau. Thực hiện một tinh chỉnh nhỏ để sử dụng các khóa mảng kiểu Ruby / PHP nhưng nếu không thì hoạt động rất tốt.
nickb

5

Cái này bỏ qua các giá trị null / không xác định

export function urlEncodeQueryParams(data) {
    const params = Object.keys(data).map(key => data[key] ? `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}` : '');
    return params.filter(value => !!value).join('&');
}

5

Trong ES7, bạn có thể viết điều này trong một dòng:

const serialize = (obj) => (Object.entries(obj).map(i => [i[0], encodeURIComponent(i[1])].join('=')).join('&'))

4

Một dòng để chuyển đổi Object thành Chuỗi truy vấn trong trường hợp ai đó cần lại

let Objs = { a: 'obejct-a', b: 'object-b' }

Object.keys(objs).map(key => key + '=' + objs[key]).join('&')

// result will be a=object-a&b=object-b

4

Tôi có một giải pháp đơn giản hơn, không sử dụng bất kỳ thư viện của bên thứ ba nào và đã được sử dụng trong bất kỳ trình duyệt nào có "Object.keys" (còn gọi là tất cả các trình duyệt hiện đại + edge + eg):

Trong ES5

function(a){
    if( typeof(a) !== 'object' ) 
        return '';
    return `?${Object.keys(a).map(k=>`${k}=${a[k]}`).join('&')}`;
}

Trong ES3

function(a){
    if( typeof(a) !== 'object' ) 
        return '';
    return '?' + Object.keys(a).map(function(k){ return k + '=' + a[k] }).join('&');
}

3

Nếu bạn muốn chuyển đổi một đối tượng lồng nhau một cách đệ quy và đối tượng có thể có hoặc không chứa các mảng (và các mảng có thể chứa các đối tượng hoặc mảng, v.v.), thì giải pháp phức tạp hơn một chút. Đây là nỗ lực của tôi.

Tôi cũng đã thêm một số tùy chọn để chọn nếu bạn muốn ghi lại cho từng thành viên đối tượng ở độ sâu nào trong đối tượng chính và chọn nếu bạn muốn thêm nhãn cho các thành viên đến từ mảng được chuyển đổi.

Tốt nhất bạn nên kiểm tra xem tham số điều thực sự nhận được một đối tượng hay mảng.

function thingToString(thing,maxDepth,recordLevel,markArrays){
    //thing: object or array to be recursively serialized
    //maxDepth (int or false):
    // (int) how deep to go with converting objects/arrays within objs/arrays
    // (false) no limit to recursive objects/arrays within objects/arrays
    //recordLevel (boolean):
    //  true - insert "(level 1)" before transcript of members at level one (etc)
    //  false - just 
    //markArrays (boolean):
    //  insert text to indicate any members that came from arrays
    var result = "";
    if (maxDepth !== false && typeof maxDepth != 'number') {maxDepth = 3;}
    var runningDepth = 0;//Keeps track how deep we're into recursion

    //First prepare the function, so that it can call itself recursively
    function serializeAnything(thing){
        //Set path-finder values
        runningDepth += 1;
        if(recordLevel){result += "(level " + runningDepth + ")";}

        //First convert any arrays to object so they can be processed
        if (thing instanceof Array){
            var realObj = {};var key;
            if (markArrays) {realObj['type'] = "converted array";}
            for (var i = 0;i < thing.length;i++){
                if (markArrays) {key = "a" + i;} else {key = i;}
                realObj[key] = thing[i];
            }
            thing = realObj;
            console.log('converted one array to ' + typeof realObj);
            console.log(thing);
        }

        //Then deal with it
        for (var member in thing){
            if (typeof thing[member] == 'object' && runningDepth < maxDepth){
                serializeAnything(thing[member]);
                //When a sub-object/array is serialized, it will add one to
                //running depth. But when we continue to this object/array's
                //next sibling, the level must go back up by one
                runningDepth -= 1;
            } else if (maxDepth !== false && runningDepth >= maxDepth) {
                console.log('Reached bottom');
            } else 
            if (
                typeof thing[member] == "string" || 
                typeof thing[member] == 'boolean' ||
                typeof thing[member] == 'number'
            ){
                result += "(" + member + ": " + thing[member] + ") ";
            }  else {
                result += "(" + member + ": [" + typeof thing[member] + " not supported]) ";
            }
        }
    }
    //Actually kick off the serialization
    serializeAnything(thing);

    return result;

}

Cảm ơn về cách tiếp cận đệ quy
Sherlock

3

Bổ sung cho giải pháp được chấp nhận, điều này hoạt động với các đối tượng và mảng đối tượng:

parseJsonAsQueryString = function (obj, prefix, objName) {
    var str = [];
    for (var p in obj) {
        if (obj.hasOwnProperty(p)) {
            var v = obj[p];
            if (typeof v == "object") {
                var k = (objName ? objName + '.' : '') + (prefix ? prefix + "[" + p + "]" : p);
                str.push(parseJsonAsQueryString(v, k));
            } else {
                var k = (objName ? objName + '.' : '') + (prefix ? prefix + '.' + p : p);
                str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
                //str.push(k + "=" + v);
            }
        }
    }
    return str.join("&");
}

Cũng đã thêm objName nếu bạn đang sử dụng các tham số đối tượng như trong các phương thức hành động của asp.net mvc.


3

Một chút nhìn tốt hơn

objectToQueryString(obj, prefix) {
    return Object.keys(obj).map(objKey => {
        if (obj.hasOwnProperty(objKey)) {
            const key = prefix ? `${prefix}[${objKey}]` : objKey;
            const value = obj[objKey];

            return typeof value === "object" ?
                this.objectToQueryString(value, key) :
                `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
        }

        return null;
    }).join("&");
}

3

Tôi đã thực hiện một so sánh các chuỗi ký tự JSON và kết quả như sau:

JSON:    {"_id":"5973782bdb9a930533b05cb2","isActive":true,"balance":"$1,446.35","age":32,"name":"Logan Keller","email":"logankeller@artiq.com","phone":"+1 (952) 533-2258","friends":[{"id":0,"name":"Colon Salazar"},{"id":1,"name":"French Mcneil"},{"id":2,"name":"Carol Martin"}],"favoriteFruit":"banana"}
Rison:   (_id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'logankeller@artiq.com',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258')
O-Rison: _id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'logankeller@artiq.com',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258'
JSURL:   ~(_id~'5973782bdb9a930533b05cb2~isActive~true~balance~'!1*2c446.35~age~32~name~'Logan*20Keller~email~'logankeller*40artiq.com~phone~'*2b1*20*28952*29*20533-2258~friends~(~(id~0~name~'Colon*20Salazar)~(id~1~name~'French*20Mcneil)~(id~2~name~'Carol*20Martin))~favoriteFruit~'banana)
QS:      _id=5973782bdb9a930533b05cb2&isActive=true&balance=$1,446.35&age=32&name=Logan Keller&email=logankeller@artiq.com&phone=+1 (952) 533-2258&friends[0][id]=0&friends[0][name]=Colon Salazar&friends[1][id]=1&friends[1][name]=French Mcneil&friends[2][id]=2&friends[2][name]=Carol Martin&favoriteFruit=banana
URLON:   $_id=5973782bdb9a930533b05cb2&isActive:true&balance=$1,446.35&age:32&name=Logan%20Keller&email=logankeller@artiq.com&phone=+1%20(952)%20533-2258&friends@$id:0&name=Colon%20Salazar;&$id:1&name=French%20Mcneil;&$id:2&name=Carol%20Martin;;&favoriteFruit=banana
QS-JSON: isActive=true&balance=%241%2C446.35&age=32&name=Logan+Keller&email=logankeller%40artiq.com&phone=%2B1+(952)+533-2258&friends(0).id=0&friends(0).name=Colon+Salazar&friends(1).id=1&friends(1).name=French+Mcneil&friends(2).id=2&friends(2).name=Carol+Martin&favoriteFruit=banana

Ngắn nhất trong số đó là Ký hiệu đối tượng URL .


2

ok, đó là một bài viết cũ hơn nhưng tôi đang đối mặt với vấn đề này và tôi đã tìm thấy giải pháp cá nhân của mình .. có thể có thể giúp đỡ người khác ..

     function objToQueryString(obj){
        var k = Object.keys(obj);
        var s = "";
        for(var i=0;i<k.length;i++) {
            s += k[i] + "=" + encodeURIComponent(obj[k[i]]);
            if (i != k.length -1) s += "&";
        }
        return s;
     };

2

Các câu trả lời trên điền không hoạt động nếu bạn có nhiều đối tượng lồng nhau. Thay vào đó, bạn có thể chọn hàm param từ đây - https://github.com/ledgeledgecode/jquery-param/blob/master/jquery-param.js Nó hoạt động rất tốt với tôi!

    var param = function (a) {
    var s = [], rbracket = /\[\]$/,
        isArray = function (obj) {
            return Object.prototype.toString.call(obj) === '[object Array]';
        }, add = function (k, v) {
            v = typeof v === 'function' ? v() : v === null ? '' : v === undefined ? '' : v;
            s[s.length] = encodeURIComponent(k) + '=' + encodeURIComponent(v);
        }, buildParams = function (prefix, obj) {
            var i, len, key;

            if (prefix) {
                if (isArray(obj)) {
                    for (i = 0, len = obj.length; i < len; i++) {
                        if (rbracket.test(prefix)) {
                            add(prefix, obj[i]);
                        } else {
                            buildParams(prefix + '[' + (typeof obj[i] === 'object' ? i : '') + ']', obj[i]);
                        }
                    }
                } else if (obj && String(obj) === '[object Object]') {
                    for (key in obj) {
                        buildParams(prefix + '[' + key + ']', obj[key]);
                    }
                } else {
                    add(prefix, obj);
                }
            } else if (isArray(obj)) {
                for (i = 0, len = obj.length; i < len; i++) {
                    add(obj[i].name, obj[i].value);
                }
            } else {
                for (key in obj) {
                    buildParams(key, obj[key]);
                }
            }
            return s;
        };

    return buildParams('', a).join('&').replace(/%20/g, '+');
};

2

GIẢI PHÁP ES6 ĐỂ KIẾM TIỀN CHUẨN MẠNH CỦA MỤC TIÊU JAVASCRIPT

const params = {
  a: 1,
  b: 'query stringify',
  c: null,
  d: undefined,
  f: '',
  g: { foo: 1, bar: 2 },
  h: ['Winterfell', 'Westeros', 'Braavos'],
  i: { first: { second: { third: 3 }}}
}

static toQueryString(params = {}, prefix) {
  const query = Object.keys(params).map((k) => {
    let key = k;
    const value = params[key];

    if (!value && (value === null || value === undefined || isNaN(value))) {
      value = '';
    }

    switch (params.constructor) {
      case Array:
        key = `${prefix}[]`;
        break;
      case Object:
        key = (prefix ? `${prefix}[${key}]` : key);
        break;
    }

    if (typeof value === 'object') {
      return this.toQueryString(value, key); // for nested objects
    }

    return `${key}=${encodeURIComponent(value)}`;
  });

  return query.join('&');
}

toQueryString (params)

"a=1&b=query%20stringify&c=&d=&f=&g[foo]=1&g[bar]=2&h[]=Winterfell&h[]=Westeros&h[]=Braavos&i[first][second][third]=3"

2

Đây là một giải pháp sẽ hoạt động cho các phụ trợ .NET ra khỏi hộp. Tôi đã lấy câu trả lời chính của chủ đề này và cập nhật nó để phù hợp với nhu cầu .NET của chúng tôi.

function objectToQuerystring(params) {
var result = '';

    function convertJsonToQueryString(data, progress, name) {
        name = name || '';
        progress = progress || '';
        if (typeof data === 'object') {
            Object.keys(data).forEach(function (key) {
                var value = data[key];
                if (name == '') {
                    convertJsonToQueryString(value, progress, key);
                } else {
                    if (isNaN(parseInt(key))) {
                        convertJsonToQueryString(value, progress, name + '.' + key);
                    } else {
                        convertJsonToQueryString(value, progress, name + '[' + key+ ']');
                    }
                }
            })
        } else {
            result = result ? result.concat('&') : result.concat('?');
            result = result.concat(`${name}=${data}`);
        }
    }

    convertJsonToQueryString(params);
    return result;
}

1

Tôi đã viết một gói chỉ dành cho điều đó: chuỗi truy vấn đối tượng :)

Hỗ trợ các đối tượng lồng nhau, mảng, chức năng mã hóa tùy chỉnh, vv Nhẹ & jQuery miễn phí.

// TypeScript
import { queryString } from 'object-query-string';

// Node.js
const { queryString } = require("object-query-string");

const query = queryString({
    filter: {
        brands: ["Audi"],
        models: ["A4", "A6", "A8"],
        accidentFree: true
    },
    sort: 'mileage'
});

trả lại

filter[brands][]=Audi&filter[models][]=A4&filter[models][]=A6&filter[models][]=A8&filter[accidentFree]=true&sort=milage

0

Chỉ là một cách khác (không có đối tượng đệ quy):

   getQueryString = function(obj)
   {
      result = "";

      for(param in obj)
         result += ( encodeURIComponent(param) + '=' + encodeURIComponent(obj[param]) + '&' );

      if(result) //it's not empty string when at least one key/value pair was added. In such case we need to remove the last '&' char
         result = result.substr(0, result.length - 1); //If length is zero or negative, substr returns an empty string [ref. http://msdn.microsoft.com/en-us/library/0esxc5wy(v=VS.85).aspx]

      return result;
   }

alert( getQueryString({foo: "hi there", bar: 123, quux: 2 }) );

0

Tham khảo từ câu trả lời @ user187291, thêm "isArray" làm tham số để tạo mảng json lồng nhau được chuyển đổi.

data : {
                    staffId : "00000001",
                    Detail : [ {
                        "identityId" : "123456"
                    }, {
                        "identityId" : "654321"
                    } ],

                }

Để tạo ra kết quả:

staffId = 00000001 & Chi tiết [0] .identityId = 123456 & Chi tiết [1] .identityId = 654321

serialize = function(obj, prefix, isArray) {
        var str = [],p = 0;
        for (p in obj) {
            if (obj.hasOwnProperty(p)) {
                var k, v;
                if (isArray)
                    k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
                else
                    k = prefix ? prefix + "." + p + "" : p, v = obj[p];

                if (v !== null && typeof v === "object") {
                    if (Array.isArray(v)) {
                        serialize(v, k, true);
                    } else {
                        serialize(v, k, false);
                    }
                } else {
                    var query = k + "=" + v;
                    str.push(query);
                }
            }
        }
        return str.join("&");
    };

    serialize(data, "prefix", false);

0

Bạn cũng có thể đạt được điều này bằng cách sử dụng JavaScript đơn giản .

const stringData = '?name=Nikhil&surname=Mahirrao&age=30';
    
const newData= {};
stringData.replace('?', '').split('&').map((value) => {
  const temp = value.split('=');
  newData[temp[0]] = temp[1];
});

console.log('stringData: '+stringData);
console.log('newData: ');
console.log(newData);


1
Đây là một bài tập tốt, nhưng đây là cách khác. Không phải là một câu trả lời cho câu hỏi.
Christiaan Westerbeek
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.