URL编码相关知识整理

最近在进行做相关需求时,遇到URL自定义编码的相关问题,之前对URL编码没有做太多整理,借此做下总结。

1.为何要进行URL编码

预备知识:

  1. URI( Universal Resource Identifier)统一资源标识
  2. URL(Universal Resource Locator) 统一资源定位器,是URI的一种

在进行HTTP传输时,通常需要将相关参数拼接到访问的URL字符串中,用&符号串联起来,例如: http://test.com/test?a=xx&b=xxx 。但是如果url中的参数出现特殊字符(=,“ 等等特殊符号)时,就会出现URL的解析错误。那么URL编码就是为了解决这种问题。

另一方面,Url的编码格式采用的是ASCII码,而不是Unicode。这也就是说你不能在Url中包含任何非ASCII字符(例如中文),否则如果客户端浏览器和服务端浏览器支持的字符集不同的情况下,中文可能会造成问题。

综上我们所说的,URL的编码实际是对URI的编码,URI编码是为了解决不安全字符的问题,除了英文字符,其他不安全的符号原则上都需要进行转义,以满足传输和解析要求。

2.怎么进行URL编码

2.1 编码规范

URL编码原则:就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。

在实际生产中,基本使用RFC3986文档规范。RFC3986文档规定:,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。有一些字符(: / \ ? # [ ] @)是用作分隔不同组件的。例如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和查询参数,等等。还有一些字符(!$&’()*+,;=)用于在每个组件中起到分隔作用的,如=用于表示查询参数中的键值对,&符号用于分隔查询多个键值对。当组件中的普通数据包含这些特殊字符时,需要对其进行编码。

RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ]

Url编码通常也被称为百分号编码(Url Encoding,also known as percent-encoding),是因为它的编码方式非常简单,使用%百分号加上两位的字符——0123456789ABCDEF——代表一个字节的十六进制形式

Url编码默认使用的字符集是US-ASCII。例如a在US-ASCII码中对应的字节是0x61,那么Url编码之后得到的就是%61,我们在地址栏上输入http://g.cn/search?q=%61%62%63,实际上就等同于在google上搜索abc了。又如@符号在ASCII字符集中对应的字节为0x40,经过Url编码之后得到的是%40。

对于非ASCII字符,需要使用ASCII字符集的超集进行编码得到相应的字节,然后对每个字节执行百分号编码。对于Unicode字符,RFC文档建议使用utf-8对其进行编码得到相应的字节,然后对每个字节执行百分号编码。如"中文"使用UTF-8字符集得到的字节为0xE4 0xB8 0xAD 0xE6 0x96 0x87,经过Url编码之后得到"%E4%B8%AD%E6%96%87"。

2.2 编码使用

python url 编码:

import urllib
rawurl=xxx
url=urllib.unquote(rawurl)

#urllib.unquote()目的是对url编码进行解码,
#与该函数对应的是编码函数urllib.quote()

java url 编码:

//将application/x-www-form-urlencoded字符串
//转换成普通字符串
//必须强调的是编码方式必须正确,如baidu的是gb2312,而google的是UTF-8
String keyWord = URLDecoder.decode("%E6%96%87%E6%A1%A3", "gb2312");
System.out.println(keyWord);

//将普通字符串转换成
//application/x-www-form-urlencoded字符串
//必须强调的是编码方式必须正确,如baidu的是gb2312,而google的是UTF-8
String urlStr = URLEncoder.encode("文档", "gb2312");
System.out.println(urlStr);

bash url 编码:


sql=` sed  -e 's/%/%25/g' \
   -e 's/ /+/g' \
   -e 's/!/%21/g' \
   -e 's/"/%22/g' \
   -e 's/#/%23/g' \
   -e 's/\&/%26/g' \
   -e 's/'\''/%27/g' \
   -e 's/(/%28/g' \
   -e 's/)/%29/g' \
   -e 's/:/%3A/g' \
   -e 's/\./%2E/g' \
   -e 's/,/%2C/g' \
   -e 's/@/%40/g' \
   -e 's/=/%3D/g' \
   -e 's/\\$/%24/g' \
   -e 's/-/%2D/g' \
   -e 's/>/%3E/g' \
   -e 's/</%3C/g' \
   -e 's/\//%2F/g' <<'EOF'
select count(*) from a.test where name='张三' and card like '%abc%'
EOF
`
#linux中对普通文本处理比较麻烦,而且网络上利用xxd 进行编码有些问题。
#因此,就自己进行特殊字符转码。实际就是利用sed命令对特殊字符转16进制进行百分号替换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值