JS 中对URL传参包含特殊字符的处理

JS 中对URL传参包含特殊字符的处理

辛勤工做的一周又悄么声的过去,感受一周立刻过去了,应该干点啥,具体干点啥,嗯~~不敢问,不敢说,不敢想,啊哈,灵机一动,仍是小结一篇文章表示曾经来过(这篇文章就在吃着川川的煎饼中英勇蛋生了!!!)。php

本文由“十有八九”投稿,若有错误,欢迎指正。html

声明文章参考一些博客,文章来源在文章末尾指出,若是遗漏,欢迎指出。python

文章总结背景

在项目中不少时候会遇到URL中带有特殊字符的传参问题,后端接收到错误的参数信息,致使功能失败。后端

特殊字符的含义(十六进制):浏览器

符号 解释 转义
# 用来标志特定的文档位置 %23
% 对特殊字符进行编码 %25
& 分隔不一样的变量值对 %26
+ 在变量值中表示空格 %2B
/ 表示目录路径 %2F
\ 表示目录路径 %5C
= 用来链接键和值 %3D
? 表示查询字符串的开始 %3F
空格 空格 %20
. 句号 %2E
: 冒号 %3A

针对上面提出的问题,普通的解决方法---正则替换解决,先来秀一波:bash

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?”,避免被吐槽,赶忙去复习总结了下各方法的区别,但愿对读到这篇文章的你能有所帮助。url

escape(str)方法

escape(str)方法生成新的由十六进制转义序列替换的字符串。

escape函数是全局对象的属性。该方法不会对ASCII字母和数字进行编码,其余全部的字符都会被转义序列替换,其中对中文编码使用Unicode字符集,下面特殊字符除外:@ * _ + - ./

字符的十六进制形式,其代码单元值为0xFF或更小,是一个两位数的转义序列:%xx。对于具备更大代码单元的字符,使用四位数格式%u xxxx。

代码示例以下:

escape('中文&hello@world') // %u4E2D%u6587%26hello@world
escape('abc123');        // abc123
escape('?');            // "%u0107"
复制代码

\color{#FF8C00}{注:该特性已经从Web标准中删除,虽然一些浏览器目前仍然支持它,但也许会在将来的某个时间中止支持,请尽可能不要使用该特性。}

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"
复制代码

方法总结

  1. escape()除了ASCII字母、数字和特定的符号外(@ * _ + - ./*),对传进来的字符串所有进行转义编码,所以若是想对URL编码,最好不要使用此方法。(该特性已经从Web标准中删除)
  2. encodeURI() 用于编码整个URI,由于URI中的合法字符都不会被编码转换
  3. encodeURIComponent()方法在编码单个URIComponent(指请求参数)应当是最经常使用的,它能够将参数中的中文、特殊字符进行转义,而不会影响整个URL。
  4. encodeURI()和encodeURIComponent()对中文的编码方式同样,一个中文3个十六进制的转义序列组成,默认编码字符集为UTF-8。

参考文章:

JAVASCRIPT中URL 传递参数(特殊字符)解决方法及转码解码的介绍

encode()

拓展:

ES5/标准 ECMAScript内置对象

相关文章
相关标签/搜索