javauri编码_URL的编码和解码
URL的编码和解码
1 为什么要URL编码
在因特⽹上传送URL,只能采⽤ASCII字符集
也就是说URL只能使⽤英⽂字母、阿拉伯数字和某些标点符号,不能使⽤其他⽂字和符号,即
只有字母和数字[0-9a-zA-Z]、⼀些特殊符号$-_.+!*'()[不包括双引号]、以及某些保留字(空格转换为+),才可以不经过编码直接⽤于URL
这意味着 如果URL中有汉字,就必须编码后使⽤。 但是⿇烦的是 标准的国际组织并没有规定具体的编码⽅法,⽽是交给应⽤程序(浏览器)⾃⼰决定。 这导致"URL编码"成为了⼀个混乱的领域。
url编码处理如果包含中⽂,其实会⾃动编码的,⽐如Chrome和⽕狐,"⽂"和"章"的utf-8编码分别是"E6 96 87"和"E7 AB A0" ,下图所⽰
的"%e6%96%87%e7%ab%a0"就是按照顺序,在每个字节前加上%⽽得到的:
但是不同的浏览器可能会有不同的编码⽅式,不要将编码交给浏览器。应该⽤JS在前端对URL编码,这样就实现了统⼀
如果key=value这种传参⽅式中,value中包含?``=或者&等符号,url的解析会变得很困难
不同的操作系统、浏览器、不同的⽹页字符集(charset)有不同的默认编码⽅式,要有⼀个统⼀格式来发送url,参考⽂章中举了4个例⼦(很有读的必要)!
2 如何编码
URL编码通常也被称为百分号编码(percent-encoding),是因为它的编码⽅式⾮常简单:
使⽤%加上两位的字符——0123456789ABCDEF——代表⼀个字节的⼗六进制形式。URL编码要做的,就是将每⼀个⾮安全的ASCII字符都被替换为“%xx”格式,
对于⾮ASCII字符,RFC⽂档建议使⽤utf-8对其进⾏编码得到相应的字节,然后对每个字节执⾏百分号编码。
如"中⽂"使⽤UTF-8字符集得到的字节为0xE4 0xB8 0xAD 0xE6 0x96 0x87,经过Url编码之后得到"%E4%B8%AD%E6%96%87"。⼀些常见的特殊字符换成相应的⼗六进制的值:
+ %20
/ %2F
%3F
% %25
# %23
& %26
2.1 JS的三种编码函数
上⾯说了编码⽅式的混乱,那么如何统⼀呢?
**使⽤Javascript先对URL编码,或者将可以在后台编码的参数编码后再发送给前端使⽤。然后再向服务器提交,不要给浏览器插⼿的机会,这样就能保证客户端只⽤⼀种编码⽅法向服务器发出请求 **
escape
js中编码出⽣最早的⼀个,不提倡使⽤,真正作⽤是:
返回⼀个字符的Unicode编码值,为的是⽅便他们能在所有计算机上可读,规则:
所有空格、标点以及其他⾮ASCII字符都⽤%xx编码替换; 例如空格返回的是%20 字符值⼤于255的字符以%uxxxx格式储存
encodeURI函数(推荐使⽤)
这个函数才是javascript中真正⽤来对URL编码的函数
它着眼于对整个URL进⾏编码,因此除了常见的符号以外,对其他⼀些在⽹址中有特殊含义的符号"; / ? : @ & = + $ , #",也不进⾏编码。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。
需要注意的是,它不对单引号'编码
它对应的解码函数是decodeURI()。
规则就是我上⾯第⼆部分所说的,采⽤utf-8编码。⽐如:
encodeURIComponent函数(推荐使⽤)
与encodeURI()的区别是,它⽤于对URL的组成部分进⾏个别编码,⽽不⽤于对整个URL进⾏编码。
因此,"; / ? : @ & = + $ , #",这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码,具体的编码规则是和encodeURI函数是⼀样的
它对应的解码函数是decodeURIComponent()。
实验:
利⽤chrome的开发者⼯具:
可以看到第⼀种,对需要url编码的部分⽤encodeURIComponent函数,其他部分不编码符合要求,即
对需要编码的参数⽤encodeURIComponent函数最推荐
2.2 我们的问题
遇到的问题:
get请求的路径参数filePath为:/image/5cf4adbe16ad4fc18ab2259cb86bb14d.png,
在相应的控制器Controller中:
@RequestMapping(path = "/admin/{filePath}")
那么这个请求就变成了:
由于服务器⽆法解析上⾯的url,导致400 bad request错误
2.3 Java的de("需要编码的参数","UTF-8")
⽐较JS的encodeURIComponent函数和Java的de("需要编码的参数","UTF-8")函数:
对//中国/images/head_tripletown.png//!@#$%^&*()进⾏URL编码:
//JS的encodeURIComponent函数
javascript:encodeURIComponent("//中国/images/head_tripletown.png//!@#$%^&*()")
"%2F%2F%E4%B8%AD%E5%9B%BD%2Fimages%2Fhead_tripletown.png%2F%2F!%40%23%24%25%5E%26*()" //Java的de("需要编码的参数","UTF-8")函数
%2f%2f%e4%b8%ad%e5%9b%bd%2fimages%2fhead_tripletown.png%2f%2f!%40%23%24%25%5e%26*()
可以看到⼀模⼀样,因此:
使⽤Javascript先对URL编码,或者将可以在后台编码的参数编码后再发送给前端使⽤。
3 为什么两次编码
⾸先看例⼦,原始请求:
其中,Controller中的映射⽂件:
@RequestMapping(path = "/admin/image/filePath/{filePath}/{width}/{height}")
对filePath参数⼀次编码后,发起URL请求:
在加断点:
毫⽆反应。。。所以应该在⼯作前就对URL进⾏了解码对filePath参数两次编码后,发起URL请求:
在加断点:
⼀次解码之前:
⼀次解码之后:
获得了正常回应:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。