注意:本文章讨论范围是默认请求的方式或者form表单形式的请求。
问题:
1、当我们用angular2(angular4,angular5,angular6,angular7,angular8,angular9)原始的http请求请求后端的时候,如果请求参数中有"+","@",":","$",",","=","?","/"等特殊符号,比如我们填写的是"test+test",用get请求:
那么传过去的最终的url为:
2、那么这会导致什么问题呢?
因为我们这里传输的是"赤裸裸"的加号"+",那么后端在解析这种字符的时候,会将其替换为空格,所以,我们用chrome的DevTools的Network面板查看的转化参数为:
发现是"test test",中间的"+"变成了空格,这就导致如果后端的数据包含了加号"+",但是我们会查不出来;
根源:
1、我们跟踪基础的请求服务:
通常的结构都是这样,构建一个默认的HttpParams的参数,然后用http服务去请求后端,然后我们跟踪这个HttpParams:
这是声明类,注意到上面有对应的实现类:
我们看下fesm2015下的http.js,发现实现类:
如果默认的options中什么都不传,那么使用HttpUrlEncodingCodec类,继续跟踪这个类:
发现调用了这个standardEncoding,跟踪这个方法:
发现这个方法把我们转码的字符串又给replace掉了,罪魁祸首找到了。
解决:
1、问题找到了,就很好解决了。
前面我们发现,HttpParams的构造函数可以接口options参数,所以我们改写这个类,然后传入改写后类的实例就行了。
我们只保留standardEncoding(v)方法的encodeURIComponent部分,后面的replace不要了;
然后传入:
_this.params = new HttpParams({
encoder: _this.commonHttpCodec
});
然后我们查看效果:
用chrome的DevTools的Network面板查看的转化参数为:
也是好的,后台可以返回包含加号"+"的结果。
后记:
第一次碰到遇到这个问题,刚开始也是不知道什么原因,一下是追溯过程:
先用Chrome的DevTools的Sources面板,查看我传的值有没有问题:
发现传的的确是:test+test,所以这里没问题;
然后跟踪我们封装的http那一层方法:
通过这里,我们可以直接看到:
是这个文件,然后在这个文件上,点击鼠标右键,在弹出的菜单中选择: Reveal in sidebar
就找到了Babel编译过的文件。
利用Chrome的DevTools帮我们一步一步找到源头。