编码
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
一般为避免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