在您阅读我的答案之前,我想说我同意@Neil。我们必须选择战斗。我们通常想尽力而为,但有时讨论的空间太小,我们不得不违背自己的意愿做出决定。
无论如何,在尼尔的回答中,我又想念一件事。文件资料。只是为了确保开发人员知道POST请求/search
是安全的。
那就是。
1.有机会
GET
首先考虑该选项。查看此问题网址的最大长度。评估最长的查询字符串是否超过2000个字符。如果不是,并且您不希望如此,请使用GET
。这看起来很丑陋,但是至少您可以为URL添加书签,当然,它具有从该方法的语义(幂等,安全和缓存)中获得的所有优点。
1.1尝试编码查询字符串
例如,在base 64中。甚至javascript也支持base 64编码。
这是这样的:
- 使用所有过滤器构建JSON并将其标准化。
- 解析成字符串
- 编码
- 发送编码的JSON作为请求参数(
/search?q=SGVsbG8gV29ybGQh....
)。
- 在服务器端,解码参数q。
- 反序列化JSON字符串
以前,请使尽可能长的JSON字符串,对其进行编码并取其长度。评估编码的字符串是否适合URL。我在Fiddle.js上实现了以下代码段,供您测试。(我希望它仍然有效)1
Base 64编码是确定性和可逆的,因此不会发生冲突。
使用编码查询,我们还可以将搜索保存在数据库中,为URL加上书签,共享链接等。当然,我们不必转义/取消转义字符串。
1.2尝试使用别名
在阅读有关如何设计REST API的博客时,我想起了另一种选择。常见查询的别名。
我觉得这些很有趣,原因如下
缩短查询字符串的长度。它使API更加干净和用户友好
GET / tickets /?status = closed&closedAt = xxx vs
GET / tickets / recently-closed /
可与更多别名或更多请求参数结合使用。
GET / tickets /?status = closed&closedAt = xxx&within = 30min vs
GET / tickets / recents -closed /?within = 30min
我们可以将别名与编码的查询字符串结合使用
GET / tickets /?status = closed&closedAt = xxx&within = 30min vs
GET / tickets / recently-closed /?q = SGVsbG8g ...
1:我使用了JSON,但是我们可以在服务器端反序列化它之后就可以使用其他格式。
search?q=t
,search?q=te
,search?q=test
,等等。考虑限制查询的发送频率,以免损害服务器。您也可以选择返回大量信息,并在客户端进行过滤。如果用户输入可以将范围缩小很多的广泛类别,则效果很好。