Axios 中 get 请求时传递特殊字符
Axios 中 get 请求时传递特殊字符
起因
这周做一个筛选查询的需求,需要传递一个包含筛选条件的数组作为 get
请求的参数。由于后端设置的参数格式是对整个筛选条件进行编码。
举例:传递参数为
where: [{"field":"dataType","op":"equal","value":"0"}]
时候(where为字段名),
后端要求的格式是
where=%5B%7B%22field%22%3A%22dataType%22%2C%22op%22%3A%22equal%22%2C%22value%22%3A%220%22%7D%5D
初步方案
经过了解,对 URL 进行编码的有两种方法:encodeURI()
和 encodeURIComponent()
两者最大的区别就是 encodeURI()
用于对一个完整的URL进行编码,而 encodeURIComponent()
适用于对URL的组成部分进行个别编码,而不用与对整个URL进行编码
踩坑
于是,我自然而然地使用 encodeURIComponent()
对筛选条件进行编码。
然后,接口依然报错。打开控制台发现,中括号并没有被编码。
如果所示,不仅中括号没有被编码,连逗号也没有。
这就很难受,查看代码中的请求写法。
然而代码有条不紊地执行着,应该是OK的啊?
再探
无奈之下,打开 Axios
翻起来源码,找到了在创建 xhr 请求时,对请求参数做了一个 buildUrl
的处理。源码路径为: axios/lib/helper/builderUrl.js
。这个文件中我们可以找到对参数进行编码的函数
具体行为是将参数做了encodeURIComponent
编码处理,但是,但是!!!然后又把下面的特殊字符转义回去了。所以我们可以看到逗号和中括号在请求的 URL 中没有被编码
最后
Axios
做这样的处理也是情理之中,因为这些字符通常有着特殊的含义,所以要对其进行特殊转义处理。
那么我们怎么解决bug呢?
修改源码?自然是不可取的,太粗暴了。
其实方法很简单,参数不放在 params
里面,就不会被 Axios
进行 特殊的编码处理。
Axios
对 URL 的处理没有那么复杂,仅仅是执行了combineURLs
,文件路径:(axios/lib/helpers/combineURLs.js)
我们直接手动对参数进行编码然后拼接成字符串,再拼回 URL 中就可以完美解决这个问题了。
再放一个修改前的代码,作为对比参考: