9

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

4 回答 4

9

通常的方法是这样做:

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

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

于 2009-01-11T00:15:43.143 回答
4

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

真是丑。

另一方面,如果您可以不使用 POST,那么 JSON 是一种来回传递此类信息的非常好的方法。

于 2009-01-11T00:19:05.413 回答
3

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

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

将会:

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

数组答案应该与普通答案不同的原因是,解码层可以自动区分不太常见的 foo 情况(恰好有一个元素的数组)和极其常见的 fred 情况(单个元素)。

这个符号可以外推到:

?highlight_mode[7]=蓝色&highlight_mode[9]=黄色

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

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

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

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

于 2009-01-11T01:51:15.230 回答
1

这段代码适用于我的 Python 后端-

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

于 2019-09-04T07:43:18.913 回答