Table of Contents
URL定义
URL是统一资源定位符(英语:Uniform Resource Locator或称统一资源定位器、定位地址、URL地址)的缩写,俗称网页地址简称网址,是因特网上标准的资源的地址(Address)如同在网络上的门牌,它最初是由蒂姆·伯纳斯-李发明用来作为万维网的地址。
统一资源定位符的标准格式如下:
[协议类型]://[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]
统一资源定位符的完整格式如下:
[协议类型]://[访问资源需要的凭证信息]@[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]
其中[访问凭证信息]、[端口号]、[查询]、[片段ID]都属于选填项,常见的协议有FTP、HTTP、HTTPS、TELNET等。
URL编码规范
URL编码的最新规范是:RFC3986
URL编码的原理
RFC3986给出的URL编码规则如下:
- 字符'a' ~ 'z'、'A' ~ 'Z'、'0' ~ '9'、.、*、-、_都不被重新编码,维持原值;
- 空格' '被转换为加号+;
- 其他每个字节都被表示成%xy格式的由3个字符组成的字符串,xy编码与Base16完全一样;
注意:有些字符可以不进行编码的,比如!、~,所以,RFC3986描述的URL编码规则有一些建议性的东西,不是一个确定的算法。所以,千万不要用URL编码之后的字符串做是否相等的比较,因为你如果不能确切的知道, 你所使用的URL编码的库对哪些字符进行了编码的话,很有可能出现不相等的情况。
URL地址为了让包含特殊字符的URL网址可以使用,必须通过%xx编码处理,这也是URL为什么需要编码/解码的原因,例如我们常用的钉钉报警机器人就需要对URL进行编码操作:
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import java.net.URLEncoder; public class Test{ public static void main(String[] args) throws Exception{ Long timestamp = System.currentTimeMillis(); String secret = "this is secret"; String stringToSign = timestamp + "\n" + secret; Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256")); byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)),"UTF-8"); System.out.println(sign); } }
Shell脚本中URL编解码实现
大部分情况下使用Java/Scala/GoLang等开发报警接口相对较重,通过Shell则较为轻便。但是比较遗憾的是dingding机器人官方文档并没有提供相应的示例,需要开发人员自动实现,为了方便大家开发将URL编码和解码脚本贴出来:
URL编码
#!/bin/bash urldecode() { # urldecode <string> local url_encoded="${1//+/ }" printf '%b' "${url_encoded//%/\\x}" } urldecode "$1"
用法如下:
$ urldecode.sh "foo%20bar" foo bar
URL解码
#!/bin/bash urlencode() { # urlencode <string> old_lang=$LANG LANG=C old_lc_collate=$LC_COLLATE LC_COLLATE=C local length="${#1}" for (( i = 0; i < length; i++ )); do local c="${1:i:1}" case $c in [a-zA-Z0-9.~_-]) printf "$c" ;; *) printf '%%%02X' "'$c" ;; esac done LANG=$old_lang LC_COLLATE=$old_lc_collate } urlencode "$1"
用法如下:
$ urlencode.sh "foo bar" foo%20bar
评论(0)