当前位置: 首页 > 科技观察

面试官敢问我URLEncode和Gbk、Unicode等编码

时间:2023-03-19 17:24:23 科技观察

URLencodeURLencode其实是对URI进行编码,而不是对URL进行编码。什么是URI?统一资源标识符(URI,UniformResourceIdentifier)是用来标识一个资源的字符串。它规定了如下语法:从上图可以看出,一个有效的URI至少包含scheme、:和path(路径),比如触发操作系统的emailaction的经典Mailto格式[1]:mailto:john.doe@example.com└──┬──┘└────────────────────────────────┘SchePath其他可选组合路径,例如scheme://hostpath?query#fragment将是我们常用的url格式:userinfohostport┌──┴────┐┌────────┴─────────┐┌┴┐https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top└─┬─┘└──────────────────────────────────────────────────────e──────────────────┘└┬┘schemeauthoritypathqueryfragmentURI包含URLsandURNsURL:UniformResourceLocator(统一资源定位器):定义了如何查找资源URN:UniformResourceName(统一资源名称):定义了这个简单的说,资源的唯一名称就是:URL:我们的地址当前网站,用什么协议(http,ftp)访问,地址路径在哪里(bilibili.com,abc.com)等。URN:我要获取的资源有一个唯一的名字。如果我过去提供,统一中心会解析URN。无论资源迁移到哪里,只要它存在,它就会归还给你。移动URL后,它不再是有效地址,您需要一个新地址来定位此资源。由于历史原因,URN一直没有流行起来,所以在某种程度上,URL和URI看起来很相似。ReservedCharacters(保留字符)URI规定以下字符应保留用于特殊用途:!*'();:@&=+$,/?#[]来自RFC3986section2.2ReservedCharacters(January2005),如?参数,/用于分割url,&用于拼接query等,保留字符各有作用。因此,当需要传递此类字符而不是作为特殊字符使用时,不能直接将其放入url中,需要进行编码,这就是urlencode的作用。encode很简单,转换保留字符如?转化为ASCII[2]的十六进制表示(?是3F),在前面加一个%表示这是一个编码字符,即?需要编码成%3F放在url中,所以url编码也叫Percent-encoding。在实际应用中如下url中,需要传入跳转BACK_URL参数new_login.com?a=12时,是否需要传递?follow=g.https://third_party_login.com?BACK_URL=new_login.com?a=12应该将其转换为https://third_party_login.com?BACK_URL=new_login.com%3Fa%3D12这样下面的?and=不会被处理,但可以作为BACK_URL参数的一部分传递给后端。http协议中headers的content-type中常见的application/x-www-form-urlencoded规定了请求体应该是URL编码的。gbk、Unicode、UTF-8鉴于珠玉在先,我梳理一下Unicode和UTF-8的区别?[3]的内容还可以:简单来说:Unicode就是“字符集”UTF-8就是“编码规则”字符集:给每个“字符”分配一个唯一的ID(学名是codepoint/codepoint/CodePoint)编码规则:将“码点”转换成字节序列的规则(编码/解码可以理解为加密/解密过程)详细过程:国人对ASCII码进行了扩充改造,产生了GB2312码,可表示6000多个常用汉字。汉字太多,包括繁体字和各种字,所以产生了GBK编码,其中包含了GB2312中的编码,扩充了很多。中国是一个多民族国家,几乎每个民族都有自己独立的语言系统。为了表示那些字符,GBK码继续扩展为GB18030码。每个国家,比如中国,都有自己的语言编码,所以出现了各种各样的编码。如果不安装对应的代码,就无法说明对应的代码想表达什么。终于,一个叫ISO(国际标准化组织)的组织看不下去了。他们一起创建了一个名为UNICODE(通用多八位字节编码字符集)的代码,它非常大,可以容纳世界上任何文本和标志。所以只要电脑有UNICODE编码系统,不管世界上是什么文字,你只要把文件保存成UNICODE编码,其他电脑就可以正常解读了。直到因特网的出现,Unicode才得以长期推广。为了解决Unicode如何在网络上传输的问题,出现了很多面向传输的UTF(UCSTransferFormat)标准。在UNICODE的网络传输中,出现了UTF-8和UTF-16两种标准,分别传输8位和16位。UTF-8,顾名思义,就是一组以8位为编码单元的变长编码。那么有人会有疑惑,既然UTF-8可以保存这么多的字符和符号,为什么国内还有这么多人使用GBK等编码呢?因为UTF-8等编码的体积比较大,占用的计算机空间也很大。大部分用户是中国人,也可以使用GBK等编码。直到因特网的出现,Unicode才得以长期推广。为了解决Unicode如何在网络上传输的问题,出现了很多面向传输的UTF(UCSTransferFormat)标准。顾名思义,UTF-8每次都是8位。一位传输数据,而UTF-16是一次传输16位。UTF-8是Internet上使用最广泛的unicode实现。这是一种为传输而设计的编码,使编码无边界,从而可以显示世界上所有文化的字符。UTF-8最大的特点之一就是它是一种变长编码方式。它可以用1~4个字节来表示一个符号,字节长度根据不同的符号而不同。当字符在ASCII码范围内时,用一个字节表示,ASCII字符的一个字节的编码保留为它的一部分,注意unicode中一个汉字占2个字节,而unicode中的一个汉字UTF-8占用3个字节)。从unicode到utf-8不是直接对应,而是需要一些算法和规则进行转换。参考资料[1]mailto格式:https://www.wikiwand.com/en/Mailto[2]ASCII:https://www.wikiwand.com/en/American_Standard_Code_for_Information_Interchange[3]Unicode和UTF有什么区别-8?:https://www.zhihu.com/question/23374078/answer/69732605本文转载自微信公众号《山尽头写东西的缓存》,可以通过以下二维码关注。转载本文请联系写东西的cache公众号。