How should I encode dictionaries into HTTP GET query strings?

折月煮酒 提交于 2020-01-23 06:14:12

问题


An HTTP GET query string is a ordered sequence of key/value pairs:

?spam=eggs&spam=ham&foo=bar

Is, with certain semantics, equivalent to the following dictionary:

{'spam': ['eggs', 'ham'], 'foo': bar}

This happens to work well for boolean properties of that page being requested:

?expand=1&expand=2&highlight=7&highlight=9
{'expand': [1, 2], 'highlight': [7, 9]}

If you want to stop expanding the element with id 2, just pop it out of the expand value and urlencode the query string again. However, if you've got a more modal property (with 3+ choices), you really want to represent a structure like so:

{'highlight_mode': {7: 'blue', 9: 'yellow'}}

Where the values to the corresponding id keys are part of a known enumeration. What's the best way to encode this into a query string? I'm thinking of using a sequence of two-tuples like so:

?highlight_mode=(7,blue)&highlight_mode=(9,yellow)

Edit: It would also be nice to know any names that associate with the conventions. I know that there may not be any, but it's nice to be able to talk about something specific using a name instead of examples. Thanks!


回答1:


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.




回答2:


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.




回答3:


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.




回答4:


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



来源:https://stackoverflow.com/questions/432002/how-should-i-encode-dictionaries-into-http-get-query-strings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!