JS 中对URL传参包含特殊字符的处理
辛勤工作的一周又悄么声的过去,感觉一周马上过去了,应该干点啥,具体干点啥,嗯~~不敢问,不敢说,不敢想,啊哈,灵机一动,还是小结一篇文章表示曾经来过(这篇文章就在吃着川川的煎饼中英勇蛋生了!!!)。
本文由“十有八九”投稿,如有错误,欢迎指正。
声明文章参考一些博客,文章来源在文章末尾指出,如果遗漏,欢迎指出。
文章总结背景
在项目中很多时候会遇到URL中带有特殊字符的传参问题,后端接收到错误的参数信息,导致功能失败。
特殊字符的含义(十六进制):
符号 | 解释 | 转义 |
---|---|---|
# | 用来标志特定的文档位置 | %23 |
% | 对特殊字符进行编码 | %25 |
& | 分隔不同的变量值对 | %26 |
+ | 在变量值中表示空格 | %2B |
/ | 表示目录路径 | %2F |
\ | 表示目录路径 | %5C |
= | 用来连接键和值 | %3D |
? | 表示查询字符串的开始 | %3F |
空格 | 空格 | %20 |
. | 句号 | %2E |
: | 冒号 | %3A |
针对上面提出的问题,普通的解决方法---正则替换解决,先来秀一波:
replace()方法替换匹配到的第一个字符串:str.replace('abc', 'Hello') replace()方法替换匹配到的所有字符串:str.replace(/abc/g, 'hello')
js中替换字符变量如下:
str=str.replace(/\%/g,"%25");
str=str.replace(/\#/g,"%23");
str=str.replace(/\&/g,"%26");
...
不但累成🐶,还没替换完,速度超级慢,还有遗漏的没替换???。。。
同事看到了你的这段代码转换,一脸懵逼,脑袋浮现一个词形容:“What?”,避免被吐槽,赶紧去复习总结了下各方法的区别,希望对读到这篇文章的你能有所帮助。
escape(str)方法
escape(str)方法生成新的由十六进制转义序列替换的字符串。
escape函数是全局对象的属性。该方法不会对ASCII字母和数字进行编码,其他所有的字符都会被转义序列替换,其中对中文编码使用Unicode字符集,下面特殊字符除外:@ * _ + - ./
字符的十六进制形式,其代码单元值为0xFF或更小,是一个两位数的转义序列:%xx。对于具有更大代码单元的字符,使用四位数格式%u xxxx。
代码示例如下:
escape('中文&hello@world') // %u4E2D%u6587%26hello@world
escape('abc123'); // abc123
escape('?'); // "%u0107"
encodeURI(URI)方法
该encodeURI()函数通过使用1到4个转义序列来表示每个字符的UTF-8编码来对统一资源标识符(URI)编码,(对于由两个字符组成的字符,用四个转义字符编码)。
假设有一个完整的URI,那么encodeURI不会编码那些对URI有特殊意义的字符。encodeURI不会编码以下特殊字符:**! @ # $& * ( ) = : / ; ? + ' **
encodeURIComponent(URI)方法
把URI字符串采用UTF-8编码格式转化成escape格式的字符串。与encodeURI()相比,这个方法将对更多的字符进行编码,如:反斜杠(‘/’);encodeURIComponent 转义除了字母、数字、(、)、.、!、~、*、'、-和_之外的所有字符。
注意:如果字符串里面包含了URI的几个部分的话,不能用这个方法来进行编码,否则 / 字符被编码之后URL将显示错误。
代码示例如下:
encodeURIComponent("123-_.!~*'()abc") // "123-_.!~*'()abc"
encodeURIComponent(";/?:@&=+$,#") // "%3B%2F%3F%3A%40%26%3D%2B%24%2C%23"
encodeURIComponent("abc123") // "abc123"
encodeURIComponent('中文&ABC/hello') //"%E4%B8%AD%E6%96%87%26ABC%2Fhello"
encodeURIComponent是被使用最多的,它是将中文等特殊字符转换成utf-8格式的url编码。
encodeURI()和encodeURIComponent()的区别
举个栗子🌰来说明一下:
现在我要使用get方式将一个参数fromUrl,传递给服务器:
var fromUrl="getList?id=1&name=zhangsan";
var getURL="http://www.XXX.cn/test.php?form="+encodeURI(fromUrl);
这里,如果使用了encodeURI,那么最终的getURL的值为:
"http://www.XXX.cn/test.php?form=getList?id=1&name=zhangsan"
这样,对参数fromUrl中的字符"&name=zhangsan",将不会作为字符串参数传递到服务器端,而是当作test.php的参数传递过去了,因为对"&name=zhangsan"中的字符"&"没有做编码。
所以,在这种应用场景下,就需要使用encodeURIComponent,编码后的getURL值为:
"http://www.XXX.cn/test.php?form=getList%3Fid%3D1%26name%3Dzhangsan"
方法总结
- escape()除了ASCII字母、数字和特定的符号外(@ * _ + - ./*),对传进来的字符串全部进行转义编码,因此如果想对URL编码,最好不要使用此方法。(该特性已经从Web标准中删除)
- encodeURI() 用于编码整个URI,因为URI中的合法字符都不会被编码转换
- encodeURIComponent()方法在编码单个URIComponent(指请求参数)应当是最常用的,它可以将参数中的中文、特殊字符进行转义,而不会影响整个URL。
- encodeURI()和encodeURIComponent()对中文的编码方式一样,一个中文3个十六进制的转义序列组成,默认编码字符集为UTF-8。
参考文章:
JAVASCRIPT中URL 传递参数(特殊字符)解决方法及转码解码的介绍
拓展: