How should I encode dictionaries into HTTP GET query strings?

This piece of code works for me with Python Backend-

import json, base64
param={
        "key1":"val1",
        "key2":[
                {"lk1":"https://www.foore.in", "lk2":"https://www.foore.in/?q=1"},
                {"lk1":"https://www.foore.in", "lk2":"https://www.foore.in/?q=1"}
                ]
        }
encoded_param=base64.urlsafe_b64encode(json.dumps(param).encode())
encoded_param_ready=str(encoded_param)[2:-1]

#eyJrZXkxIjogInZhbDEiLCAia2V5MiI6IFt7ImxrMSI6ICJodHRwczovL3d3dy5mb29yZS5pbiIsICJsazIiOiAiaHR0cHM6Ly93d3cuZm9vcmUuaW4vP3E9MSJ9LCB7ImxrMSI6ICJodHRwczovL3d3dy5mb29yZS5pbiIsICJsazIiOiAiaHR0cHM6Ly93d3cuZm9vcmUuaW4vP3E9MSJ9XX0=
#In JS
var decoded_params = atob(decodeURI(encoded_param_ready));


I've also seen people JSON-encode the nested dictionary, then further encode it with BASE64 (or something similar), then pass the whole resulting mess as a single query string parameter.

Pretty ugly.

On the other hand, if you can get away with using POST, JSON is a really good way to pass this kind of information back and forth.


In many Web frameworks it's encoded differently from what you say.

{'foo': [1], 'bar': [2, 3], 'fred': 4}

would be:

?foo[]=1&bar[]=2&bar[]=3&fred=4

The reason array answers should be different from plain answers is so the decoding layer can automatically tell the less common foo case (array which just happens to have a single element) from extremely common fred case (single element).

This notation can be extrapolated to:

?highlight_mode[7]=blue&highlight_mode[9]=yellow

when you have a hash, not just an array.

I think this is pretty much what Rails and most frameworks which copy from Rails do.

Empty arrays, empty hashes, and lack of scalar value look identical in this encoding, but there's not much you can do about it.

This [] seems to be causing just a few flamewars. Some view it as unnecessary, because the browser, transport layer, and query string encoder don't care. The only thing that cares is automatic query string decoder. I support the Rails way of using []. The alternative would be having separate methods for extracting a scalar and extracting an array from querystring, as there's no automatic way to tell when program wants [1] when it wants 4.


The usual way is to do it like this:

highlight_mode[7]=blue&highlight_mode[9]=yellow

AFAIR, quite a few server-side languages actually support this out of the box and will produce a nice dictionary for these values.