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

参考文档

声明
1.本网站名称: 盲盒博客
2.本站永久网址:https://exakit.com
3.本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长support@exakit.com
4.本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责
5.本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
6.本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新