在写上一篇博客之前,我一直对URL编码没什么概念,看到网页链接上一串百分号加数字的字符串时会短暂的想想,因为工作中也不涉及到具体的URL编码的部分,一直也没深入过,而促使我写下来记录就是上一篇博客中markdown解析的时候出了一点小问题(markdown链接是放在小括号里面的,然后放在小括号的链接本身也包含小括号,这时markdown解析出了问题),然后查问题的时候就查到了URL编码的相关知识,这几天又查阅了资料,简要写在这里,深化一下记忆。
什么是URL编码
什么是URL?URL是Uniform Resource Locator(统一资源定位符)的缩写,就是平常说的网页地址,像www.google.com
就是个URL。而URL编码就是把URL里面的字符按照一定的规则标准进行编码,产生一个国际范围内通用的字符串(ASCII码串),这里是Wiki上URL编码的解释,可以看到Wiki上的关键词是percent-encoding,因为URL编码针对每个字符的编码都使用%做前缀转义字符。
为什么需要URL编码
URL就是统一为网络上资源命名,万维网遍及世界,所以URL需要具有通用性(世界范围内通用,跨语言,跨地区时区),具有通用性的同时还要有完整性,不能因为URL中带了一些特殊字符就导致URL在传输过程中丢失了信息(比如URL中带有某个特定国家的文字),否则就失去了URL的意义,定位不到资源,因此RFC1738网络标准对URL做了硬性的规定(可以在上面的链接里看到具体RFC1738对URL的规定),除了一些ascii字符和特殊的保留字符可以直接用于URL,其他的字符都需要经过编码才可以用于表示URL,这样经过标准规则对URL进行编码,所有的特殊字符都可以用标准中规则的字符进行编码,世界范围内使用相同的规则,编码解码达成一致,通用性和完整性都得到了保证。
URL编码的规则标准
当前的URL编码标准是对所有URL标准内的保留字符不进行百分号的编码,其他的一律先转换成UTF-8的字节(每个单独的字节转换为十六进制位再在前面都加百分号)表示,再在其前面加上百分号(%)。下面用简单的例子来演示一下URL编码标准的过程。
简单例子
因何而起,便以何结束,既然是上次写的博客,就以上次博客地址为例(只取一个汉字做为例子,不按个分析演示了),地址是https://bugcode.net/2017/02/05/闭包等于匿名函数吗
,这里只取闭
这个字,来演示URL编码的过程:
汉字不是RFC1738标准中规则的保留字,所以要取
闭
字的UTF-8编码,其对应的十六进制Unicode码是95ED
。再将对应的Unicode码转换为对应的UTF-8字节,转换需要UTF-8转换表,通过转换表,获取当前
95ED
对应的UTF-8字节序列,下面是一张UTF-8转换表:
unicode | UTF-8 |
---|---|
0000 - 007F | 0####### |
0080 - 07FF | 11##### 10###### |
0800 - FFFF | 1110#### 10###### 10###### |
10000 - 1FFFFF | 11110#### 10###### 10###### 10###### |
上面表格中左侧是Unicode码对应范围,右侧是UTF-8对应字节序列表示,#代表对应Unicode码对应的二进制位,依次填入,后面不够的补0,具体可以查阅UTF-8编码规则相关资料,
95ED
对应范围在0800 - FFFF范围内,即闭
字需要三个字节表示。HEX(95ED
) = BIN(10010101 11101101
),对应转换表,可得到对应的UTF-8字节序列分别是(把95ED
二进制位分别按位填入1110#### 10###### 10######
的#位置中)第一个字节需要填入4位,即:
1110 1001
第二个字节填入6位,即:
10 010111
第三个字节填入6位,即:
10 101101
三个字节对应的二进制位,再转换为十六进制分别是:
BIN(
1110 1001
) = HEX(E9
)BIN(
10 010111
) = HEX(97
)BIN(
10101101
) = HEX(AD
)根据规则,标准之内的保留字不需要填加%前缀转义进行编码,最后上面的链接
https://bugcode.net/2017/02/05/闭
(只取一个汉字做例子演示,其余同理)经过URL编码之后就是https://bugcode.net/2017/02/05/%E9%97%AD
最后用JS的encodeURI函数来验证一下结果:
1
2
3
4
5
6
7
8
9<html>
<body>
<script type="text/javascript">
document.write(encodeURI("https://bugcode.net/2017/02/05/闭")+ "<br />")
</script>
</body>
</html>代码输出:
https://bugcode.net/2017/02/05/%E9%97%AD