我应该如何将字典编码为HTTP GET查询字符串?

时间:2009-01-11 00:06:26

标签: http query-string

HTTP GET查询字符串是键/值对的有序序列:

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

具有某些语义,等同于以下字典:

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

这恰好适用于所请求页面的布尔属性:

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

如果要停止展开ID为2的元素,只需将其从expand值中弹出,然后再次对查询字符串进行urlencode。但是,如果你有一个更多的模态属性(有3个以上的选择),你真的想要代表一个这样的结构:

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

其中相应id键的值是已知枚举的一部分。将此编码为查询字符串的最佳方法是什么?我正在考虑使用像这样的两元组序列:

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

编辑:了解与约定相关联的任何名称也会很高兴。我知道可能没有,但很高兴能够使用名称而不是示例来讨论具体的事情。谢谢!

4 个答案:

答案 0 :(得分:8)

通常的做法是这样做:

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

AFAIR,很多服务器端语言实际上支持这种开箱即用,并会为这些值生成一个很好的词典。

答案 1 :(得分:4)

我还看到人们对嵌套字典进行JSON编码,然后使用BASE64(或类似的东西)对其进行进一步编码,然后将整个结果混乱作为单个查询字符串参数传递。

非常难看。

另一方面,如果你可以使用POST,JSON是一种非常好的方式来回传递这种信息。

答案 2 :(得分:3)

在许多Web框架中,它的编码方式与您所说的不同。

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

将是:

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

数组答案的原因应该与普通答案不同,因此解码层可以从非常常见的fred案例(单个元素)中自动告诉不太常见的foo案例(恰好具有单个元素的数组)。

这种表示法可以推断为:

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

当你有一个哈希,而不仅仅是一个数组。

我认为这几乎是Rails和大多数从Rails复制的框架所做的。

空数组,空哈希值和缺少标量值在此编码中看起来完全相同,但是你无能为力。

这[]似乎只引起了一些火焰战争。有些人认为这是不必要的,因为浏览器,传输层和查询字符串编码器并不在意。唯一关心的是自动查询字符串解码器。我支持使用[]的Rails方式。另一种方法是使用单独的方法来提取标量并从查询字符串中提取数组,因为没有自动的方法来判断程序何时需要[1]。

答案 3 :(得分:0)

这段代码对我来说适用于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));