Abfragezeichenfolgencodierung eines Javascript-Objekts

481

Kennen Sie eine schnelle und einfache Möglichkeit, ein Javascript-Objekt in ein Objekt zu codieren string, das ich über eine GETAnfrage übergeben kann?

Nein jQuery, keine anderen Frameworks - einfach nur Javascript :)

Napolux
quelle
Warum kann JQuery keine Lösung sein, wenn es eine geeignete für Ihre Lösung gibt?
eaglei22
@ eaglei22, da ich zu der Zeit an einem Projekt für ein IPTV-Set-Top-Box-Gerät arbeitete und keine externen Bibliotheken erlaubt waren. ;-)
Napolux
1
Danke für die Antwort. Ich sehe diese Spezifikation von Zeit zu Zeit und habe mich immer gefragt, warum. Nun, jetzt habe ich eins, danke! :)
eaglei22
9
@ eaglei22 Da Sie manchmal keine große Bibliothek laden möchten, um ein Element anhand der ID zu erhalten.
Aaron Harun
Die meisten Browser unterstützen URLSearchParamsjetzt ...
mb21

Antworten:

810

so was?

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

Bearbeiten: Dieser konvertiert auch rekursive Objekte (unter Verwendung der PHP-Array-Notation für die Abfragezeichenfolge).

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

Benutzer187291
quelle
2
Wird es nicht bei {foo: [1,2,3], bar: "100%"} brechen?
Quentin
1
@Ofri: Für POST-Anforderungen an einen Server, der für den Empfang eingerichtet wurde, ist JSON eine gute Wahl. Wenn Sie bei GET-Anforderungen etwas anderes als ein paar einfache Parameter an den Server senden, ist Ihr Design wahrscheinlich falsch.
Tim Down
2
@Marcel Das liegt daran, dass die Funktion nicht nach hasOwnProperty sucht. Ich habe Ihre Geige so aktualisiert, dass sie jetzt funktioniert: jsfiddle.net/rudiedirkx/U5Tyb/1
Rudie
1
@ TimDown Bezüglich Ihres Kommentars senden Sie einfache Parameter in GET-Anforderungen. Ich stimme nicht zu. Das Gruppieren von Parametern in Arrays kann nützlich sein, da PHP auf der Serverseite ein festes assoziatives Array zum Mitnehmen findet. Ich kann nicht verstehen, warum dies als Design falsch ist.
Savas Vedova
1
Ist das 'if (obj.hasOwnProperty (prop))' notwendig? Die for in Anweisung Schleife direkt über den Eigenschaften des Objekts, so dass der Aufruf von hasOwnProperty immer als wahr ausgewertet wird
Arnon
231

jQuery hat eine Funktion dafür. jQuery.param()Wenn Sie sie bereits verwenden, können Sie diese verwenden: http://api.jquery.com/jquery.param/

Beispiel:

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

str enthält jetzt width=1680&height=1050

benvds
quelle
119
unter Berufung auf Napolux (das OP): "einfach nur Javascript" . : P
Sk8erPeter
6
jQuery.param () hat ein unheimliches Verhalten. Versuchen Sie var a = [] auszuführen; a [2564] = 12; console.log (jQuery.param ({propertyylist: a})); um zu sehen was ich meine.
Uhr
13
@akond In der jQuery-Dokumentation wird ausdrücklich angegeben, dass Sie möglicherweise kein nacktes Array übergeben.
Ariel
4
@Ariel Er geht nicht in einem nackten Array vorbei. Er übergibt ein Array mit nur einem Wert am Index 2564. Zur Demonstration: var a = []; a[5] = 'foo'; jQuery.param({ parameters: a }); Ergebnisse in "parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=foo". Was zwar richtig ist, aber möglicherweise nicht das ist, was Sie erwarten.
Chris Hall
4
Frage hat speziell Vanilla JS
Bug Hunter 219
189

Einfach verwenden URLSearchParamsDies funktioniert in allen aktuellen Browsern

new URLSearchParams(object).toString()
nullaber
quelle
5
Nein, da es keine rekursiven Objekte gibt
Eddie Monge Jr
Funktioniert nicht mit verschachtelten Objekten. let j = { m: 5, n: { k: 1 } }; new URLSearchParams(j).toString(); // result "m=5&n=%5Bobject+Object%5D"
Hitautodestruct
19
@EddieMongeJr Abfragezeichenfolgen sind von Natur aus Schlüssel-Wert-Paare. Sie sollten nicht einmal verschachtelte Objekte serialisieren möchten. Diese Antwort ist der moderne Weg. Upvotes erforderlich.
Romain Durand
5
Ja, es handelt sich um Schlüsselwertpaare, aber nichts sagt aus, dass der Wert kein mit Zeichenfolgen codiertes Objekt sein kann. In den ursprünglichen Fragen wird auch nach einem "Javascript-Objekt in eine Zeichenfolge" gefragt, das verschachtelte Eigenschaften haben kann
Eddie Monge Jr
@EddieMongeJr Selbst die akzeptierte Antwort (und die anderen nach einem kurzen Blick) unterstützt kein verschachteltes Objekt. Sie können stringifydie verschachtelten Objekte, bevor Sie könnenURLSearchParams
Mosh Feu
128
Object.keys(obj).reduce(function(a,k){a.push(k+'='+encodeURIComponent(obj[k]));return a},[]).join('&')

Bearbeiten: Ich mag diesen Einzeiler, aber ich wette, es wäre eine populärere Antwort, wenn er semantisch mit der akzeptierten Antwort übereinstimmt:

function serialize( obj ) {
    let str = '?' + Object.keys(obj).reduce(function(a, k){
        a.push(k + '=' + encodeURIComponent(obj[k]));
        return a;
    }, []).join('&');
    return str;
}
sergk
quelle
1
Eine Standleitung für die Reduktionsfunktion würde jedoch die Lesbarkeit erheblich verbessern.
Aurelien Ribon
54
Die Verwendung von .map () anstelle von .reduce () wäre noch einfacher: Object.keys(obj).map(k => k + '=' + encodeURIComponent(obj[k])).join('&')
Jannes
2
Nur um zu beachten, dass Object.keysnur in IE> = 9
Johnston
5
Weiter verbesserter @ Jannes-Code unter Verwendung von ES6-Vorlagen anstelle von Verkettung -Object.keys(obj).map(k => `${k}=${encodeURIComponent(obj[k])}`).join('&')
csilk
1
Falls Ihre Schlüssel auch encodeUriComponent need benötigen: Object.entries(obj).map(e => e.map(ee => encodeURIComponent(ee)).join('=')).join('&');
Blaise
112

Hier ist ein Einzeiler in ES6:

Object.keys(obj).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`).join('&');
Nico Tejera
quelle
Ersetzen Sie Schlüssel w / k und Sie sind golden
Jamie Kudla
17
Warnung! Dies funktioniert nur bei flachen Objekten. Wenn Sie eine Eigenschaft der obersten Ebene haben, die ein anderes Objekt ist, gibt dieser eine Liner "key =% 5Bobject% 20Object% 5D" aus. Nur als Heads-Up.
Andrew Allbright
4
Dies spuckt auch keine Arrays aus. Ich habe bekommen, export?actions[]=finance,create,editwann es sein sollte, export?actions[]=finance&actions[]=create&actions[]=editwie es der schreckliche Standard ist.
Darkbluesun
3
Arrays sind so gut wie immer "Sie sind auf sich allein gestellt", da URL-Argumente in Bezug auf die Spezifikation nur Zeichenfolgen sind. Sie müssen also festlegen, dass alles, was keine einzelne Zeichenfolge ist, vom Server korrekt gelesen wird du rufst an actions[]ist PHP-Notation; Django verwendet actionstattdessen mehrere (kein []Suffix); Einige andere ORM / CMS erfordern durch Kommas getrennte Listen usw. "Wenn es sich also nicht um einfache Zeichenfolgen handelt, stellen Sie zunächst sicher, dass Sie wissen, was Ihr Server überhaupt will."
Mike 'Pomax' Kamermans
Sehr elegante Lösung!
Anh Tran
51

Mit Node.js v6.6.3

const querystring = require('querystring')

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

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

Referenz: https://nodejs.org/api/querystring.html

Lucas Constantino Silva
quelle
8
Dies sollte IMO nicht herabgestuft werden. Wenn es sich um JS auf dem Server handelt, sollte dies die richtige Antwort sein.
Michael Benin
4
Es scheint, dass es keine verschachtelten Objekte unterstützt.
Yarin Gold
43

Ich schlage vor, die URLSearchParamsSchnittstelle zu verwenden:

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

Oder indem Sie das Suchobjekt wie folgt an den Konstruktor übergeben:

const obj = {foo: "hi there", bar: "100%" };
const params = new URLSearchParams(obj).toString();
bmaggi
quelle
1
Interessanter Vorschlag, aber beachten Sie, dass die Browserunterstützung für diese Funktion immer noch sehr lückenhaft ist.
mrec
Wenn Sie den IE (der derzeit ziemlich verbreitet ist) und einige bestimmte mobile Versionen nicht unterstützen, ist dies die beste Antwort, da es sich um einfaches JavaScript handelt.
Marcos Sandrini
24

Eine kleine Änderung der von user187291 akzeptierten Lösung:

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

Das Überprüfen auf hasOwnProperty für das Objekt macht JSLint / JSHint glücklich und verhindert, dass versehentlich Methoden des Objekts oder andere Dinge serialisiert werden, wenn das Objekt alles andere als ein einfaches Wörterbuch ist. Anweisungen auf dieser Seite finden Sie im folgenden Abschnitt: http://javascript.crockford.com/code.html

jssebastian
quelle
14

Nun, jeder scheint seinen Einzeiler hierher zu bringen, also hier geht meins:

const encoded = Object.entries(obj).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&");
Alex Escalante
quelle
1
Object.entries wird im IE nicht unterstützt.
MBouwman
@MBouwman natürlich, IE ist jenseits von Gut und Böse kaputt, deshalb muss man babel / core-js
chpio verwenden
@chpio Babel / core-js unterstützt Object.entries nicht, wenn ich recht habe.
MBouwman
Core unterstützt Object.entries: github.com/zloirock/core-js/blob/master/… und sogar die alte Corejs2-Babel-Laufzeittransformation unterstützt dies ebenfalls. github.com/babel/babel/blob/…
chpio
12

Müssen Sie beliebige Objekte senden? In diesem Fall ist GET eine schlechte Idee, da die Länge der URLs, die Benutzeragenten und Webserver akzeptieren, begrenzt ist. Mein Vorschlag wäre, ein Array von Name-Wert-Paaren zum Senden aufzubauen und dann eine Abfragezeichenfolge aufzubauen:

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() );
Tim Down
quelle
11

Rails / PHP Style Query Builder

Diese Methode konvertiert ein Javascript-Objekt in ein URI Query String. Behandelt auch verschachtelte Arrays und Objekte (in Rails/ PHPSyntax):

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

Anwendungsbeispiel:

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
Sheharyar
quelle
Schönes Beispiel. Ich habe einen Tippfehler in Ihrer Antwort behoben. Übrigens wäre es interessant, wenn Sie Ihre bearbeiten function, um falsyWerte auszuschließen (null, undefiniert, NaN, '') ...
developer033
8

Verwenden Sie JSON.

Schauen Sie sich diese Frage an, um Ideen für die Implementierung zu erhalten.

Ofri Raviv
quelle
2
Ich weiß nicht, in was er den Server schreibt, aber die meisten modernen Sprachen haben gute Pakete, die JSON lesen. Außerdem ist es besser, einen JSON-lesenden Servercode zu implementieren, als selbst ein neues Codierungsschema zu erfinden, selbst wenn er es am Ende implementiert. DIY-Codierungen wie diese sind in der Regel fehlerhaft (da Sie normalerweise nicht an alle möglichen Fälle denken, z. B. an den Wert eines Arrays an sich usw.).
Ofri Raviv
Schlagen Sie grundsätzlich vor, das Objekt in JSON zu konvertieren und dann die gesamte JSON-Zeichenfolge als einzelnen GET-Abfrageparameter an den Server zu übergeben?
Marco Demaio
8

Hier ist die Coffeescript-Version der akzeptierten Antwort. Dies kann jemandem Zeit sparen.

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("&")
alf
quelle
Danke alfonso! Wirklich meine Zeit gespart!
Lukas
6

Hier ist eine kurze und rekursive Version mit Object.entries . Es verarbeitet beliebig verschachtelte Arrays, jedoch keine verschachtelten Objekte. Außerdem werden leere Elemente entfernt:

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

Z.B:

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"
Mikebridge
quelle
Diese Version hat den Job für mich erledigt, wenn es um verschachtelte Arrays ging. Die Verwendung von Ruby / PHP-Array-Schlüsseln wurde leicht angepasst, funktioniert aber ansonsten hervorragend.
Nickb
5

Dieser überspringt null / undefinierte Werte

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

In ES7 können Sie dies in einer Zeile schreiben:

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

Einzelne Zeile zum Konvertieren von Object in Query String, falls jemand es erneut benötigt

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
Laravel Plus
quelle
4

Ich habe eine einfachere Lösung, die keine Bibliothek von Drittanbietern verwendet und bereits in jedem Browser mit "Object.keys" (auch bekannt als alle modernen Browser + Rand + dh) verwendet werden kann:

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

Wenn Sie ein verschachteltes Objekt rekursiv konvertieren möchten und das Objekt möglicherweise Arrays enthält oder nicht (und die Arrays können Objekte oder Arrays usw. enthalten), wird die Lösung etwas komplexer. Das ist mein Versuch.

Ich habe auch einige Optionen hinzugefügt, mit denen Sie auswählen können, ob Sie für jedes Objektelement in welcher Tiefe im Hauptobjekt aufzeichnen möchten, und ob Sie den Elementen, die aus konvertierten Arrays stammen, eine Bezeichnung hinzufügen möchten.

Idealerweise sollten Sie testen, ob der Parameter thing tatsächlich ein Objekt oder Array empfängt.

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;

}
Wytze
quelle
Vielen Dank für den rekursiven Ansatz
Sherlock
3

Ergänzung für akzeptierte Lösung, dies funktioniert mit Objekten & Array von Objekten:

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

Haben Sie auch objName hinzugefügt, wenn Sie Objektparameter wie in asp.net mvc-Aktionsmethoden verwenden.

A. Aziem Moemen
quelle
3

Ein bisschen besser aussehen

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

Ich habe einen Vergleich von JSON-Stringifizierern durchgeführt und die Ergebnisse sind wie folgt:

JSON:    {"_id":"5973782bdb9a930533b05cb2","isActive":true,"balance":"$1,446.35","age":32,"name":"Logan Keller","email":"[email protected]","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:'[email protected]',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:'[email protected]',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

Die kürzeste davon ist die URL-Objektnotation .

Niutech
quelle
2

ok, es ist ein älterer Beitrag, aber ich stehe vor diesem Problem und habe meine persönliche Lösung gefunden. Vielleicht kann ich jemand anderem helfen.

     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;
     };
hayatoShingu
quelle
2

Die obigen Antworten funktionieren nicht, wenn Sie viele verschachtelte Objekte haben. Stattdessen können Sie den Funktionsparameter hier auswählen - https://github.com/knowledgecode/jquery-param/blob/master/jquery-param.js Es hat sehr gut für mich funktioniert !

    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, '+');
};
Vandana Sharma
quelle
2

ES6-LÖSUNG FÜR DIE ABFRAGE VON JAVASCRIPT-OBJEKTEN

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"
Gandharv Garg
quelle
2

Dies ist eine sofort einsatzbereite Lösung für .NET-Backends. Ich habe die primäre Antwort dieses Threads übernommen und sie an unsere .NET-Anforderungen angepasst.

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;
}
Engel Venchev
quelle
1

Ich habe nur dafür ein Paket geschrieben: object-query-string :)

Unterstützt verschachtelte Objekte, Arrays, benutzerdefinierte Codierungsfunktionen usw. Lightweight & jQuery frei.

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

kehrt zurück

filter[brands][]=Audi&filter[models][]=A4&filter[models][]=A6&filter[models][]=A8&filter[accidentFree]=true&sort=milage
dayvee.cz
quelle
0

Nur ein anderer Weg (kein rekursives Objekt):

   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 }) );
Marco Demaio
quelle
0

Lesen Sie in der Antwort @ user187291 "isArray" als Parameter hinzu, damit das verschachtelte JSON-Array konvertiert wird.

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

                }

Um das Ergebnis zu erzielen:

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);
Langer Waldläufer
quelle
0

Sie können dies auch mit einfachem JavaScript erreichen .

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

Nikhil Mahirrao
quelle
1
Dies ist eine schöne Übung, aber umgekehrt. Keine Antwort auf die Frage.
Christiaan Westerbeek