Skip to content

编码

ascii, unicode与utf-8

全称 American standard code for information interchange.

ascii 占字符:7个 所以一共可以展示128个字符0~127 前30来个用作控制键 最后一个作删除键

iso 8859 - ascii的超集 占字符:8个 所以是0~255种表达 前128位和ascii一致,后来在此基础上又发展了iso 8859-1 and etc.包括了音标符号阿 还有欧元符号这些

微软也有自己的一些规则

非拉丁字符也有自己的几套流行规则

问题,如何才能统一呢?

那就是 unicode字符集。 前128位和ascii依然保持一致 它用 U+十六进制数字保存 比如U+0041

unicode几乎可以展示世界上所有的character(我觉得)

可参考十进制的unicode表

http://www.tamasoft.co.jp/en/general-info/unicode-decimal.html

也有emoji unicode

https://www.quackit.com/character_sets/emoji/

不过语言字符映射是一方面 存储编码是另一方面 => 每个字都32位(4个8位字节) 岂不是很浪费吗。所以一般采用utf-8的编码方式,它可以采用灵活的长度。

ref: https://www.sitepoint.com/guide-web-character-encoding/

【注意 也不是说utf-8是最好的 它得到了存储空间 那必定会等价的牺牲掉性能。所以在web应用内一般用utf-8,python用utf-8,java用utf-16。

ref: https://foofish.net/unicode_utf-8.html

注意它们的称谓:

character => unicode Decimal/hexadecimal NCRs(numeric character refrence) => utf-8 Code

与前端相关的编码

好用的查询编码工具网站:http://www.endmemo.com/unicode/unicodeconverter.php

HTML部分

【编码方式】

response里的:

content-type: text/html; charset=UTF-8

等同于也就是h5的默认编码

不过h4的默认编码不是utf-8 是ISO-8859-1 仅支持256个不同的字符。所以会需要手动设定一下。

(ref: https://www.w3schools.com/html/html_charset.asp

【html entity】

何谓html entity?也就是除去reserved word以外的,可以在html上展示出来的有意义字符。

那若是想展现reserved word该怎么办呢?可以用它的最本真方式——unicode来写(事实上所有的文字都可以参考unicode表,这么写,比如可以用😂来表达emoji的笑脸噢)。

规则如下:

&#十进制unicode;

&#x十六进制unicode;

&HTML特定entityname;

记住entityName会好写很多,因为它们都是有意义的。比如常用的lt和gt 还有nbsp

image-20230221171026318

一般为避免xss攻击破坏dom结构 需要特别对< > " ' 进行编码

URL部分

url被创造出来的时候是用的ascii字符集,也就是仅支持基本的英文符号,并且不支持空格;所以url有两种字符都需要被额外编码:

①空格和ascii编码以外的字符 比如中文

②url里的revserved word 比如 /

url的编码因为用%号作为编码标志 所以又被称为百分号编码

它的编码规则如下:

将字符的UTF-8编码按空格分开,在空格前加%。

比如 / 的utf-8是 2F => %2F

空格 的utf-8是20 => %20

万 的utf-8是E4 B8 87 0A => %E4%B8%87%0A

一般而言浏览器、xmlhttprequest和fetch(存疑)都替我们做了这一步,当我们在地址栏里输入 https://www.google.com/?q=哈哈哈 再复制这一段地址时,复制出来的已经变成了被encode的形式。

(ref: https://www.w3schools.com/tags/ref_urlencode.asp

【encodeURIComponent与encodeURI】

其实就是按照这两个api的命名来。

encodeURI是对包括协议在内的链接所有部分进行encode,因为要维持链接的正确形式,所以encodeURI是不会动入参里的url保留字的 比如https://和/,e.g.:

encodeURI('https://www.google.com/search?q=哈哈') => "https://www.google.com/search?q=%E5%93%88%E5%93%88"

而encodeURIComponent是为了对部分内容做encode,所以会编码整个入参:

encodeURIComponent('https://www.google.com/search?q=哈哈') => "https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3D%E5%93%88%E5%93%88"

那它们何时有用呢?

encodeURIComponent作用比较大,当需要在链接的queryString里加复杂参数时,需要对参数的值进行整体编码,以去除参数内url关键词的干扰。比如我们app跳小程序携带的参数就作了编码。

再比如queryString库的encode(https://github.com/Gozala/querystring/blob/master/encode.js)与decode(https://github.com/Gozala/querystring/blob/master/decode.js)里,连接qs与解析qs里,都对参数进行了编码与反编码。(所以如果后端对读取到的get请求中的url queryString的值没进行url decode就进行操作的话,是不对的哟)

而encodeURI对常人而言作用相比没那么大,不过decodeURI可以在别人给你复制了一大段被编码过的代码时,回归到你肉眼可以识别出里头有哪些文字的状态。

CSS 部分

伪类的content 规则如下:

\十六进制unicode

各种 content-type

耶!终于到了…我一直不甚清楚的地方了…

请求头与返回头里都有content-type

请求头的content-type

在post/put下,客户端需要告诉服务端传输的data类型是什么。get下是不存在传输的请求体,也不存在content-type的。

常用的”application/x-www-form-urlencoded, application/json, multipart/form-data, “

其中最本真的”application/x-www-form-urlencoded“,顾名思义,data部分会采取同url encode类似的方式编码。不过这里会把空格换成+号(https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding)。注意,后端收到数据后也要urldecode一下,不然数据会有误。

而最方便的”application/json“唯一不方便的地方就是会发预请求,需要额外处理,也会在某种程度上造成请求浪费。

写node时常用的body-parser中间件,会根据content-type对data上的数据进行还原。

返回头的content-type

Browsers will do MIME sniffing in some cases and will not necessarily follow the value of this header; to prevent this behavior, the header X-Content-Type-Options can be set to nosniff.

对于ajax而言,返回头的content-type就无需特别留意,一般都是application/json