缘起

我发现浏览器地址栏中显示的,和我将其复制粘贴到编辑器中的内容不同。

比如地址栏显示的是,https://ds63.eu.org/2022/村上春树,但当我粘贴到Vscode后,却是https://ds63.eu.org/2022/%E6%9D%91%E4%B8%8A%E6%98%A5%E6%A0%91/

编码与解码

我之前只知道形如%E6%9D%91是url编码,但没详细了解过。

根据百分号编码 - Wikiwand的介绍,过程如下:

  1. 将每个字符按照 UTF-8 编码规则转换为字节序列
  2. 将每个字节编码为 % 后跟两个十六进制数字
original_string = "村上春树"
utf8_string = original_string.encode('utf-8')
print(utf8_string)
#b'\xe6\x9d\x91\xe4\xb8\x8a\xe6\x98\xa5\xe6\xa0\x91'
hex_utf8_string =  '%'.join([f'{b:02X}' for b in utf8_string])
print(hex_utf8_string)
#E6%9D%91%E4%B8%8A%E6%98%A5%E6%A0%91
  1. 实际使用时可以用urllib.parse这个库
# 编码
from urllib.parse import quote,unquote

original_url = "https://ds63.eu.org/2022/村上春树"
encoded_url = quote(original_url, safe=':/')

print(encoded_url) #https://ds63.eu.org/2022/%E6%9D%91%E4%B8%8A%E6%98%A5%E6%A0%91/

#解码
decoded_url = unquote(encoded_url)
print(decoded_url) #https://ds63.eu.org/2022/村上春树/

显示与实际复制

那浏览器是如何实现用户看到的与实际复制不同的呢,我猜测可能是这样的:

    <div id="userFriendlyUrl" oncopy="handleCopy()">
        https://ds63.eu.org/2022/村上春树
    </div>

    <script>
        function handleCopy() {
            // 获取用户友好的URL
            var userFriendlyUrl = document.getElementById("userFriendlyUrl").innerText;

            // 对URL进行URL编码
            var encodedUrl = encodeURIComponent(userFriendlyUrl);

            // 创建一个文本区域元素,设置其值为编码后的URL
            var textarea = document.createElement("textarea");
            textarea.value = encodedUrl;

            // 将文本区域元素添加到页面中
            document.body.appendChild(textarea);

            // 选中文本
            textarea.select();
            textarea.setSelectionRange(0, 99999); // 兼容移动设备

            // 复制文本到剪贴板
            document.execCommand("copy");

            // 移除文本区域元素
            document.body.removeChild(textarea);

            // 阻止默认复制事件,避免复制原始文本
            event.preventDefault();

            //alert("URL copied: " + encodedUrl);
        }
    </script>

国际化域名

我上述的例子并没有考虑到国际化域名。

具体可参看国际化域名Punycode编码

意外收获

我之前就好奇汉字到底有多少个,看中文字符集 Unicode 编码范围,发现可能应该不到十万。

ps: 看中日韩统一表意文字 - 维基百科,自由的百科全书,还是觉得很混乱。不少是历史遗留下来的问题,所以我先前的估算显然是有问题的。

之后我又查了些资料,发现现在关于汉字的数量仍没有定论,可以说是众说纷纭。

延伸

在写这篇博客之后,我才注意到浏览器的地址栏原来有如此多的功能:

  1. 地址栏预测: 当用户输入地址栏时,浏览器会根据用户的浏览历史、收藏夹和搜索历史等信息提供地址栏预测。这有助于用户快速访问常用站点。

  2. 搜索建议: 地址栏还充当搜索栏,用户可以直接在其中输入搜索关键字。浏览器通常会基于用户的输入和搜索历史,提供搜索建议。

  3. 安全指示: 浏览器通常在地址栏中显示有关连接安全性的信息,如锁定图标或"安全"标签,以指示连接的加密状态。

  4. 国际化域名(IDN)支持: 浏览器会对国际化域名进行处理,确保它们在地址栏中正确显示,并在需要时进行Punycode编码。

  5. 复制与粘贴: 用户在地址栏中复制时,通常会复制显示的用户友好的URL,而不是编码后的URL。这是为了提高用户的可理解性。

这里打算给自己挖个坑,想试着自己实现一个地址栏。

参考链接