Codifica di query-stringa di un oggetto Javascript


482

Conosci un modo rapido e semplice per codificare un oggetto Javascript in un oggetto stringche posso passare tramite una GETrichiesta?

No jQuery, nessun altro framework - solo Javascript semplice :)


Perché JQuery non può essere una soluzione se ce n'è una appropriata per la tua soluzione?
eaglei22,

@ eaglei22 perché all'epoca stavo lavorando a un progetto per un dispositivo di decoder IPTV e non erano consentite librerie esterne. ;-)
napolux,

1
Grazie per la risposta. Vedo queste specifiche di volta in volta e mi chiedo sempre uno scenario perché. Bene, ora ne ho uno, grazie! :)
eaglei22

9
@ eaglei22 Perché a volte non vuoi caricare una libreria di grandi dimensioni per ottenere un elemento per ID.
Aaron Harun,

la maggior parte dei browser URLSearchParamsora supporta ...
mb21

Risposte:


810

come questo?

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

Modifica: questo converte anche oggetti ricorsivi (usando la notazione "array" php per la stringa di query)

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
Non si romperà dato {foo: [1,2,3], bar: "100%"}?
Quentin,

1
@Ofri: per le richieste POST a un server configurato per riceverlo, JSON è una buona scelta. Per le richieste GET, se stai inviando qualcosa di diverso da alcuni semplici parametri al server, è probabile che il tuo progetto sia sbagliato.
Tim Down,

2
@Marcel Questo perché la funzione non controlla hasOwnProperty. Ho aggiornato il tuo violino così ora lo fa: jsfiddle.net/rudiedirkx/U5Tyb/1
Rudie

1
@TimDown Per quanto riguarda il tuo commento, invia semplici parametri nelle richieste GET. Non sono d'accordo. Raggruppare i parametri in array potrebbe rivelarsi utile poiché PHP sul lato server trova un array associativo pronto all'uso. Non riesco a capire perché questo sia sbagliato come design.
Savas Vedova,

1
Il "if (obj.hasOwnProperty (prop))" è necessario? Il ciclo dell'istruzione for appena sopra le proprietà dell'oggetto, quindi chiamando hasOwnProperty viene sempre valutato come vero
Arnon,

231

jQuery ha una funzione per questo, jQuery.param()se lo stai già usando puoi usarlo: http://api.jquery.com/jquery.param/

esempio:

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

str ora contiene width=1680&height=1050


119
citando Napolux (il PO): "solo Javascript semplice" . : P
Sk8erPeter,

6
jQuery.param () ha un comportamento sinistro. Prova a eseguire var a = []; a [2564] = 12; console.log (jQuery.param ({propertylist: a})); per vedere cosa intendo.
circa

13
@akond La documentazione di jQuery specifica che non è possibile passare in un array nudo.
Ariel,

4
@Ariel Non sta passando in un array nudo. Sta passando in un array con un solo valore all'indice 2564. Per dimostrare: var a = []; a[5] = 'foo'; jQuery.param({ parameters: a }); Risultati in "parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=foo". Che, sebbene corretto, potrebbe non essere quello che ti aspetti.
Chris Hall,

4
La domanda è stata posta specificamente alla Vanilla JS
Bug Hunter 219 del

192

Basta usare URLSearchParamsQuesto funziona in tutti i browser attuali

new URLSearchParams(object).toString()

5
No perché non fa oggetti ricorsivi
Eddie Monge Jr

Non funziona su oggetti nidificati. let j = { m: 5, n: { k: 1 } }; new URLSearchParams(j).toString(); // result "m=5&n=%5Bobject+Object%5D"
hitautodestruct,

20
@EddieMongeJr Le stringhe di query sono coppie chiave-valore in base alla progettazione, non dovresti nemmeno voler serializzare oggetti nidificati. Questa risposta è la strada da percorrere moderna. Voti necessari.
Romain Durand,

5
Sì, sono coppie di valori-chiave ma non c'è nulla che dica che il valore non può essere un oggetto con codifica stringa. Inoltre, le domande originali richiedono un "oggetto Javascript in una stringa", che può avere proprietà nidificate
Eddie Monge Jr

@EddieMongeJr anche la risposta accettata (e le altre dopo una breve occhiata) non supportano l'oggetto annidato. Puoi fare stringifygli oggetti nidificati prima di farloURLSearchParams
Mosh Feu, il

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

Modifica: mi piace questo one-liner, ma scommetto che sarebbe una risposta più popolare se corrispondesse semanticamente alla risposta accettata:

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

1
Una linea dedicata per la funzione di riduzione migliorerebbe notevolmente la leggibilità.
Aurelien Ribon,

54
Usare .map () invece di .reduce () sarebbe ancora più semplice: Object.keys(obj).map(k => k + '=' + encodeURIComponent(obj[k])).join('&')
Jannes,

2
Solo per notare che Object.keysè disponibile solo in IE> = 9
Johnston,

5
Codice @Jannes ulteriormente migliorato utilizzando modelli ES6 anziché concatenazione -Object.keys(obj).map(k => `${k}=${encodeURIComponent(obj[k])}`).join('&')
csilk

1
Nel caso in cui le tue chiavi necessitino di codificare anche UriComponent ❤️: Object.entries(obj).map(e => e.map(ee => encodeURIComponent(ee)).join('=')).join('&');
Blaise,

112

Ecco una riga in ES6:

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

sostituisci chiave w / k e sei d'oro
Jamie Kudla,

17
Avvertimento! Funziona solo su oggetti poco profondi. Se si dispone di una proprietà di livello superiore che è un altro oggetto, questa riga genererà "key =% 5Bobject% 20Object% 5D". Proprio come un avvertimento.
Andrew Allbright,

4
Inoltre, questo non sputa array. Ho export?actions[]=finance,create,editcapito quando dovrebbe avere export?actions[]=finance&actions[]=create&actions[]=editlo standard terribile.
darkbluesun,

3
Le matrici sono praticamente sempre "sei da solo" perché gli argomenti URL sono solo stringhe per quanto riguarda le specifiche, quindi sei pronto per fare in modo che tutto ciò che non sia una singola stringa venga letto correttamente dal server stai chiamando. actions[]è la notazione PHP; Django usa actioninvece multipli (nessun []suffisso); alcuni altri ORM / CMS richiedono elenchi separati da virgole, ecc. Quindi "se non si tratta di stringhe semplici, assicurati innanzitutto di sapere cosa vuole persino il tuo server".
Mike 'Pomax' Kamermans,

Soluzione molto elegante!
Anh Tran,


45

Suggerisco di usare l' URLSearchParamsinterfaccia:

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

O passando l'oggetto di ricerca nel costruttore in questo modo:

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

1
Suggerimento interessante, ma tieni presente che il supporto del browser per questa funzione è ancora molto irregolare.
mrec,

Se non supporterai IE (che è abbastanza comune ora) e alcune versioni mobili specifiche, questa è la risposta migliore, dato che è un semplice JavaScript.
Marcos Sandrini,

24

Una piccola modifica alla soluzione accettata dall'utente187291:

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

Il controllo di hasOwnProperty sull'oggetto rende felice JSLint / JSHint e impedisce la serializzazione accidentale dei metodi dell'oggetto o di altre cose se l'oggetto è tutt'altro che un semplice dizionario. Vedere il paragrafo su per le dichiarazioni in questa pagina: http://javascript.crockford.com/code.html


14

Bene, tutti sembrano mettere la sua copertina qui, quindi ecco la mia:

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

1
Object.entries non è supportato in IE.
MBouwman,

@MBouwman ovviamente, IE è al di là del bene e del male, ecco perché devi usare babel / core-js
chpio,

@chpio Babel / core-js non supporta Object.entries se ho ragione.
MBouwman,

core ha il supporto per Object.entries: github.com/zloirock/core-js/blob/master/… e anche la vecchia trasformazione del runtime di babele corejs2 lo supporta anche github.com/babel/babel/blob/…
chpio

12

Devi inviare oggetti arbitrari? In tal caso, GET è una cattiva idea poiché ci sono limiti alla lunghezza degli URL accettati dagli agenti utente e dai server Web. Il mio suggerimento sarebbe di creare un array di coppie nome-valore da inviare e quindi creare una stringa di query:

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

Generatore di query in stile Rails / PHP

Questo metodo converte un oggetto Javascript in a URI Query String. Gestisce anche matrici e oggetti nidificati (in Rails/ PHPsintassi):

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

Esempio di utilizzo:

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

Bell'esempio Ho corretto un refuso nella tua risposta. A proposito, sarebbe interessante se modifichi il tuo functionper escludere falsyvalori (null, undefined, NaN, '') ...
developer033

8

usa JSON.

dai un'occhiata a questa domanda per idee su come implementare.


2
Non so in cosa stia scrivendo il server, ma la maggior parte delle lingue moderne ha buoni pacchetti che leggono JSON. Inoltre, anche se finisce per implementarlo, è meglio implementare un codice server di lettura JSON piuttosto che inventare un nuovo schema di codifica. Le codifiche fai-da-te come questa tendono ad essere buggy (perché di solito non pensi a tutti i casi possibili, come il valore che è un array in sé, ecc.).
Ofri Raviv,

stai fondamentalmente suggerendo di convertire l'oggetto in JSON e quindi passare l'intera stringa JSON al server come un singolo parametro di query GET?
Marco Demaio,

8

Ecco la versione coffeescript della risposta accettata. Questo potrebbe far risparmiare tempo a qualcuno.

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

Grazie Alfonso! Mi ha davvero salvato il tempo!
Lukas,

6

Ecco una versione concisa e ricorsiva con Object.entries . Gestisce array nidificati arbitrariamente, ma non oggetti nidificati. Rimuove anche gli elementi vuoti:

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

Per esempio:

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"

Questa versione ha funzionato per me quando ho a che fare con array nidificati. È stata apportata una leggera modifica per utilizzare i tasti array in stile Ruby / PHP, ma per il resto funziona alla grande.
Nick

5

Questo salta i valori nulli / non definiti

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

In ES7 puoi scrivere questo in una riga:

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

4

Riga singola per convertire l'oggetto in stringa di query nel caso in cui qualcuno ne abbia nuovamente bisogno

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

Ho una soluzione più semplice che non utilizza alcuna libreria di terze parti ed è già adatta per essere utilizzata in qualsiasi browser che ha "Object.keys" (aka tutti i browser moderni + edge + ie):

In ES5

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

In ES3

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

3

Se si desidera convertire ricorsivamente un oggetto nidificato e l'oggetto può contenere o meno array (e gli array possono contenere oggetti o array, ecc.), La soluzione diventa un po 'più complessa. Questo è il mio tentativo

Ho anche aggiunto alcune opzioni per scegliere se si desidera registrare per ciascun membro dell'oggetto alla profondità dell'oggetto principale in cui si trova e per scegliere se si desidera aggiungere un'etichetta ai membri che provengono da array convertiti.

Idealmente, dovresti testare se il parametro thing riceve davvero un oggetto o un 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;

}

Grazie per l'approccio ricorsivo
Sherlock,

3

Aggiunta per soluzione accettata, funziona con oggetti e array di oggetti:

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

Inoltre hai aggiunto objName se stai usando parametri oggetto come nei metodi di azione di mvc asp.net.


3

Un po 'meglio

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

Ho fatto un confronto tra i stringificatori JSON e i risultati sono i seguenti:

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

Il più breve tra questi è Notazione oggetto URL .


2

ok, è un post più vecchio ma sto affrontando questo problema e ho trovato la mia soluzione personale .. forse posso aiutare qualcun altro ..

     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

Le risposte di cui sopra non funzionano se si hanno molti oggetti nidificati. Invece puoi scegliere la funzione param da qui - https://github.com/knowledgecode/jquery-param/blob/master/jquery-param.js Ha funzionato molto bene per me!

    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

SOLUZIONE ES6 PER LA CODIFICA DI QUERY STRING DI UN OGGETTO 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

Questa è una soluzione che funzionerà per i back-end .NET. Ho preso la risposta principale di questo thread e l'ho aggiornato per soddisfare le nostre esigenze di .NET.

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

Ho scritto un pacchetto proprio per questo: object-query-string :)

Supporta oggetti nidificati, array, funzioni di codifica personalizzate ecc. Leggero e privo di jQuery.

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

ritorna

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

0

Solo un altro modo (nessun oggetto ricorsivo):

   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

Fare riferimento alla risposta @ user187291, aggiungere "isArray" come parametro per convertire l'array nidificato json.

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

                }

Per ottenere il risultato:

StaffID = 00000001 & Particolare [0] .identityId = 123456 & Particolare [1] = 654321 .identityId

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

Puoi anche raggiungere questo obiettivo utilizzando JavaScript semplice .

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
Questo è un buon esercizio, ma è il contrario. Non una risposta alla domanda.
Christiaan Westerbeek,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.