Pengkodean kueri-string pada Objek Javascript


482

Apakah Anda tahu cara cepat dan sederhana untuk menyandikan Obyek Javascript ke dalam stringyang dapat saya sampaikan melalui GETPermintaan?

Tidak jQuery, tidak ada kerangka kerja lain - Javascript biasa :)


Mengapa JQuery tidak bisa menjadi solusi jika ada solusi yang sesuai untuk solusi Anda?
eaglei22

@ eaglei22 karena pada saat itu saya sedang mengerjakan sebuah proyek untuk perangkat IPTV set top box dan tidak ada perpustakaan eksternal yang diizinkan. ;-)
napolux

1
Terima kasih atas tanggapannya. Saya melihat spesifikasi ini dari waktu ke waktu dan selalu bertanya-tanya mengapa skenario. Nah, sekarang saya dapat satu, terima kasih! :)
eaglei22

9
@ eaglei22 Karena terkadang Anda tidak ingin memuat pustaka besar untuk mendapatkan satu elemen melalui id.
Aaron Harun

sebagian besar browser mendukung URLSearchParamssekarang ...
mb21

Jawaban:


810

seperti ini?

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

Sunting: yang ini juga mengonversi objek rekursif (menggunakan notasi "array" php untuk string kueri)

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
Tidakkah akan rusak diberikan {foo: [1,2,3], bar: "100%"}?
Quentin

1
@Ofri: Untuk permintaan POST ke server yang diatur untuk menerimanya, JSON adalah pilihan yang baik. Untuk permintaan GET, jika Anda mengirim apa pun selain beberapa parameter sederhana ke server maka kemungkinan desain Anda salah.
Tim Down

2
@Marcel Itu karena fungsi tidak memeriksa hasOwnProperty. Saya telah memperbarui biola Anda jadi sekarang ia melakukannya: jsfiddle.net/rudiedirkx/U5Tyb/1
Rudie

1
@TimDown Mengenai komentar Anda yang mengirim parameter sederhana dalam permintaan GET. Saya tidak setuju. Pengelompokan parameter ke dalam array mungkin berguna karena PHP di sisi server menemukan array asosiatif yang siap pakai untuk digunakan. Saya tidak bisa melihat mengapa ini salah sebagai desain.
Savas Vedova

1
Apakah 'jika (obj.hasOwnProperty (prop))' diperlukan? Untuk dalam pernyataan loop lebih dari sifat-sifat objek sehingga memanggil hasOwnProperty selalu bernilai true
Arnon

231

jQuery memiliki fungsi untuk ini,, jQuery.param()jika Anda sudah menggunakannya Anda dapat menggunakannya: http://api.jquery.com/jquery.param/

contoh:

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

str sekarang berisi width=1680&height=1050


119
mengutip Napolux (OP): "just Javascript" . : P
Sk8erPeter

6
jQuery.param () memiliki perilaku jahat. Coba jalankan var a = []; a [2564] = 12; console.log (jQuery.param ({propertylist: a})); untuk melihat apa yang saya maksud.
akond

13
@ akond Dokumentasi jQuery secara khusus mengatakan bahwa Anda mungkin tidak lulus dalam array kosong.
Ariel

4
@ Ariel Dia tidak lewat dalam array kosong. Dia mengoper array dengan hanya satu nilai pada indeks 2564. Untuk menunjukkan: var a = []; a[5] = 'foo'; jQuery.param({ parameters: a }); Hasil dalam "parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=foo". Yang, meskipun benar, mungkin bukan yang Anda harapkan.
Chris Hall

4
Pertanyaan telah secara khusus ditanyakan Vanilla JS
Bug Hunter 219

192

Cukup gunakan URLSearchParamsIni berfungsi di semua browser saat ini

new URLSearchParams(object).toString()

5
Tidak karena tidak melakukan objek rekursif
Eddie Monge Jr

Tidak berfungsi pada objek bersarang. let j = { m: 5, n: { k: 1 } }; new URLSearchParams(j).toString(); // result "m=5&n=%5Bobject+Object%5D"
hitautodestruct

20
@EddieMongeJr String kueri adalah pasangan kunci-nilai berdasarkan desain, Anda bahkan tidak ingin membuat serial objek bersarang Jawaban ini adalah cara modern untuk pergi. Dibutuhkan upvotes.
Romain Durand

5
Ya mereka adalah pasangan nilai kunci tetapi tidak ada yang mengatakan bahwa nilai tersebut tidak dapat berupa objek yang disandikan string. Juga, pertanyaan asli meminta "Javascript Object menjadi sebuah string", yang dapat memiliki properti bersarang
Eddie Monge Jr

@ EddieMongeJr bahkan jawaban yang diterima (dan yang lain setelah melihat sebentar) tidak mendukung objek bersarang. Anda dapat stringifyobjek bersarang sebelum Anda bisaURLSearchParams
Mosh Feu

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

Sunting: Saya suka one-liner ini, tapi saya yakin itu akan menjadi jawaban yang lebih populer jika cocok dengan jawaban yang diterima secara semantik:

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

1
Jalur khusus untuk fungsi reduksi akan sangat meningkatkan keterbacaan.
Aurelien Ribon

54
Menggunakan .map () alih-alih .reduce () akan lebih mudah: Object.keys(obj).map(k => k + '=' + encodeURIComponent(obj[k])).join('&')
Jannes

2
Hanya untuk dicatat bahwa Object.keyshanya tersedia di IE> = 9
Johnston

5
Lebih lanjut meningkatkan kode @Jannes menggunakan templat ES6 alih-alih rangkaian -Object.keys(obj).map(k => `${k}=${encodeURIComponent(obj[k])}`).join('&')
csilk

1
Dalam kasus kunci Anda perlu encodeUriComponent ❤️ juga: Object.entries(obj).map(e => e.map(ee => encodeURIComponent(ee)).join('=')).join('&');
Blaise

112

Berikut ini adalah satu liner di ES6:

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

ganti kunci w / k dan kamu emas
Jamie Kudla

17
Peringatan! Ini hanya bekerja pada objek yang dangkal. Jika Anda memiliki properti tingkat atas yang merupakan objek lain, liner yang satu ini akan menampilkan "key =% 5Bobject% 20Object% 5D". Sama seperti kepala.
Andrew Allbright

4
Juga, ini tidak memuntahkan array. Saya mendapatkan export?actions[]=finance,create,editketika seharusnya memiliki export?actions[]=finance&actions[]=create&actions[]=editstandar yang mengerikan.
darkbluesun

3
Array hampir selalu "Anda sendiri" karena argumen URL hanya berupa string sejauh menyangkut spesifikasi, jadi Anda siap untuk membuat apa pun yang bukan string tunggal terbaca dengan benar oleh server Anda menelepon. actions[]adalah notasi PHP; actionSebagai gantinya, Django menggunakan banyak (tanpa []akhiran); beberapa ORM / CMS lain memerlukan daftar yang dipisahkan koma, dll. Jadi "jika ini bukan string sederhana, pertama pastikan Anda tahu apa yang bahkan diinginkan server Anda".
Mike 'Pomax' Kamermans

Solusi yang sangat elegan!
Anh Tran


45

Saya sarankan menggunakan URLSearchParamsantarmuka:

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

Atau dengan mengirimkan objek pencarian ke konstruktor seperti ini:

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

1
Saran yang menarik, tetapi perlu diketahui bahwa dukungan browser untuk fitur ini masih sangat tambal sulam.
mrec

Jika Anda tidak akan mendukung IE (yang cukup umum sekarang) dan beberapa versi seluler tertentu, ini adalah jawaban terbaik, karena ini adalah JavaScript biasa.
Marcos Sandrini

24

Amandemen kecil untuk solusi yang diterima oleh 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("&");
}

Memeriksa hasOwnProperty pada objek membuat JSLint / JSHint senang, dan mencegah metode serialisasi objek atau benda lainnya secara tidak sengaja jika objek tersebut bukan kamus sederhana. Lihat paragraf tentang pernyataan di halaman ini: http://javascript.crockford.com/code.html


14

Nah, semua orang sepertinya meletakkan satu-linernya di sini jadi ini milikku:

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

1
Object.entries tidak didukung di IE.
MBouwman

@Mouwman, tentu saja, IE rusak karena kebaikan dan kejahatan, itu sebabnya Anda harus menggunakan babel / core-js
chpio

@ chpio Babel / core-js tidak mendukung Object.entries jika saya benar.
MBouwman

core memiliki dukungan untuk Object.entries: github.com/zloirock/core-js/blob/master/… dan bahkan corejs2 babel runtime transform lama juga mendukungnya github.com/babel/babel/blob/…
chpio

12

Apakah Anda perlu mengirim objek yang sewenang-wenang? Jika demikian, GET adalah ide yang buruk karena ada batasan panjang URL yang akan diterima oleh agen pengguna dan server web. Saran saya adalah membangun array pasangan nama-nilai untuk dikirim dan kemudian membangun string kueri:

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

Pembuat Kueri Rel / Gaya PHP

Metode ini mengubah objek Javascript menjadi URI Query String. Juga menangani array dan objek bersarang (dalam Rails/ PHPsintaks):

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

Contoh penggunaan:

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

Contoh yang bagus. Saya memperbaiki kesalahan ketik dalam jawaban Anda. Omong-omong, akan menarik jika Anda mengedit functionuntuk mengecualikan falsynilai (null, undefined, NaN, '') ...
developer033

8

gunakan JSON.

lihat pertanyaan ini untuk ide-ide tentang bagaimana mengimplementasikan.


2
Saya tidak tahu dia menulis server apa, tetapi sebagian besar bahasa modern memiliki paket bagus yang membaca JSON. Selain itu, bahkan jika dia akhirnya mengimplementasikannya, lebih baik menerapkan kode server JSON-read daripada menciptakan skema pengkodean baru Anda sendiri. Pengkodean DIY seperti ini cenderung buggy (karena Anda biasanya tidak memikirkan semua kasus yang mungkin, seperti nilai menjadi array itu sendiri dll ').
Ofri Raviv

apakah Anda pada dasarnya menyarankan untuk mengubah objek menjadi JSON dan kemudian meneruskan seluruh string JSON ke server sebagai parameter permintaan GET tunggal?
Marco Demaio

8

Inilah versi coffeescript dari jawaban yang diterima. Ini mungkin menghemat waktu untuk seseorang.

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("&")

Alfonso terima kasih! Benar-benar menghemat waktu saya!
Lukas

6

Berikut ini adalah versi ringkas & rekursif dengan Object.entries . Ini menangani array bersarang sewenang-wenang, tetapi tidak objek bersarang. Itu juga menghilangkan elemen kosong:

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

Misalnya:

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"

Versi ini melakukan pekerjaan untuk saya ketika berhadapan dengan array bersarang. Membuat sedikit perubahan untuk menggunakan kunci array gaya Ruby / PHP tetapi bekerja dengan baik.
julukan

5

Yang ini melompati nilai null / undefined

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

Di ES7 Anda dapat menulis ini dalam satu baris:

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

4

Satu baris untuk mengubah Objek menjadi String Kueri jika seseorang membutuhkannya lagi

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

Saya punya solusi yang lebih sederhana yang tidak menggunakan perpustakaan pihak ketiga mana pun dan sudah cenderung untuk digunakan di browser apa pun yang memiliki "Object.keys" (alias semua browser modern + edge + ie):

Dalam ES5

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

Dalam ES3

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

3

Jika Anda ingin mengkonversi objek bersarang secara berulang dan objek mungkin atau mungkin tidak mengandung array (dan array mungkin berisi objek atau array, dll), maka solusinya menjadi sedikit lebih kompleks. Ini usaha saya.

Saya juga telah menambahkan beberapa opsi untuk memilih jika Anda ingin merekam untuk setiap anggota objek pada kedalaman apa di objek utama yang duduk, dan untuk memilih jika Anda ingin menambahkan label ke anggota yang berasal dari array yang dikonversi.

Idealnya Anda harus menguji apakah parameter benda benar-benar menerima objek atau array.

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;

}

Terima kasih atas pendekatan rekursif
Sherlock

3

Selain untuk solusi yang diterima, ini bekerja dengan objek & array objek:

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

Juga telah menambahkan objName jika Anda menggunakan parameter objek seperti pada metode aksi asp.net mvc.


3

Sedikit terlihat lebih baik

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

Saya membuat perbandingan pengali JSON dan hasilnya adalah sebagai berikut:

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

Yang terpendek di antara mereka adalah Notasi Objek URL .


2

ok, ini posting yang lebih tua tapi saya menghadapi masalah ini dan saya telah menemukan solusi pribadi saya .. mungkin dapat membantu orang lain ..

     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

Jawaban di atas tidak berfungsi jika Anda memiliki banyak objek bersarang. Alih-alih, Anda dapat memilih fungsi param dari sini - https://github.com/knowledgecode/jquery-param/blob/master/jquery-param.js Ini berfungsi sangat baik untuk saya!

    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

SOLUSI ES6 UNTUK PENCARIAN QUERY STRING DARI OBYEK 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

Ini adalah solusi yang akan bekerja untuk .NET backends di luar kotak. Saya telah mengambil jawaban utama utas ini dan memperbaruinya agar sesuai dengan kebutuhan .NET kami.

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

Saya telah menulis sebuah paket hanya untuk itu: object-query-string :)

Mendukung objek bersarang, array, fungsi penyandian khusus dll. Ringan & jQuery gratis.

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

kembali

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

0

Hanya cara lain (tidak ada objek rekursif):

   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

Rujuk dari answer @ user187291, tambahkan "isArray" sebagai parameter untuk membuat json nested array dikonversi.

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

                }

Untuk membuat hasilnya:

staffId = 00000001 & Detail [0] .identityId = 123456 & Detail [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

Anda juga dapat mencapai ini dengan menggunakan JavaScript sederhana .

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
Ini latihan yang bagus, tapi ini sebaliknya. Bukan jawaban untuk pertanyaan itu.
Christiaan Westerbeek
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.