URL Query Parameters (有时候也叫 URL Parameters)并没有明确的 RFC 规范来指明其如何传输数组或对象,在实践中不同的客户端、服务端能够轻松构造或者解析的方式也不同。
以下格式均无对错,只是 API 风格的选择
JavaScript
URLSearchParams
URLSearchParams 是各浏览器给予前端开发者用于构造、解析 URL parameters 的类。
构造数组是十分简单的,数组会转换成 key=value1&key=value2
格式的字符串。如下例所示。但这一方法并不能用于转换对象,当你传递一个 Object 给 .append
时,JavaScript 会隐式地将 Object 转成字符串 [object Object]
。
let p = new URLSearchParams()
p.append("x", 1)
p.append("x", 2)
p.toString() // 'x=1&x=2'
axios
axios 作为前端开发里最受欢迎的 HTTP 请求库之一,它选择了与 URLSearchParams 并不相同的序列化方式。
当你使用 axios.get("/", {params: {x: [1, 2]}})
时,它将会把列表序列化为 x[]=1&x[]=2
。并且 axios
支持 Object 的序列化,例如 axios.get("/", {params: {x: {sub: 1}}})
,会把参数序列化为 x=%7B%22sub%22:1%7D
。
借助 qs 的帮助,可以使用 axios 提供的序列化配置把参数序列化结果改成与 URLSearchParams 相同。
axios.get('/', {
params: {
x: [1, 2]
},
paramsSerializer: params => {
return qs.stringify(params)
}
})
Python
Tornado、Bottle、Flask、Django、Baize、Starlette 等 Python Web 框架都以 JavaScript URLSearchParams 相同的格式对 URL Parameters 进行解析,requests
也以相同的方式对 URL Query Parameters 进行构造,并且也同样并不支持 dict
的序列化和反序列化。
Java
作为 Java 的大一统 Web 框架,Spring 采用的解析方式无疑是权威的。使用 @RequestParam
可以解析 key=value1&key=value2
格式的参数。