{{TOC}}
网络知识是计算机的基础,是作为计算机从业者的基本素养。下面的内容是我阅读《网络是怎样连接的》的记录合了,也结网络进行了一些扩展。
强制缓存:直接从客户端本地获取,不向服务端请求,即使断网也能获取;这种情况下,状态码 200,在浏览器开发者工具可以看到Status Code: 200 (from memory cache)
或者Status Code: 200 (from disk cache)
。
协商缓存:客户端会向服务端请求,但不从服务端直接获取资源,而是先询问自己是否能使用缓存,“我的缓存过期了吗”,服务端会告诉客户端结果,如果没过期,客户端将直接使用缓存,如果过期了,服务端会把最新的资源送给客户端,这个过程叫协商;这种情况,状态码 304,Status Code: 304
。
和强制缓存相关的字段:Expires 和 Cache-Control;其中 Cache-Control 的值可以有很多组合,但是当值包含max-age=t1
的时候,就会在 t1 时间内不向服务端请求,而直接取缓存,t1 时间内走的是强制缓存。
和协商缓存相关的字段:ETag/If-None-Match 和 Last-Modified/If-Modified-Since。
Expires:
- HTTP1.0 字段,如果设置了 Cache-Control 的 max-age 字段,Expires 会被忽略;
- 设置具体的时间值(首次请求时服务端返回)作为缓存的过期时间,例如“
expires: Tue, 20 Sep 2022 00:47:28 GMT
”; - 过期时间由服务端确定,而客户端时间并非一致(时区、用户主动调节时间),缓存无法预期,只要客户端时间以任何理由超过 expires,缓存将失效。
关于用户主动调时,因为技术透明,用户介入主动受害(缓存失效);关于时区,技术结果,用户被动受害(缓存失效)。
Cache-Control:
- HTTP1.1 字段,设置相对时间控制缓存过期时间;
- public(任何地方缓存,客户端或者代理);
- private(只允许客户端缓存);
- no-cache(协商缓存,使用缓存前问服务端自己的缓存过期了没);
- no-store(禁用缓存,机密文件不想客户端缓存)
- max-age=(单位是秒), s-maxage=(优先级高于 max-age= 和 expires,仅适用共享缓存);
- max-stale[=](表示客户端愿意接受已过期资源,但是不能超过给定时间);
cache-control: max-age=315360000
表示过期时间(新鲜度)一年,一年内内,可以绕过请求服务端,直接使用缓存;Cache-Control: no-cache
——使用缓存之前要请求服务端,验证缓存是否仍然有效,不能绕过服务端,另外Cache-Control: max-age=0, must-revalidate
相当于 no-cache。
If a response includes both an Expires header and a max-age directive, the max-age directive overrides the Expires header, even if the Expires header is more restrictive --- RFC2016,同时有 max-age 和 expires,expires 将被覆盖
Last-Modified / If-Modified-Since:
- 第一次请求服务器返回 Last-Modefied 后浏览器保存为 If-Modified-Since;
- 之后浏览器每次发出请求,若未命中强制缓存,则携带 IMS;
- 服务器对比最后修改时间,如果修改时间一致,返回 304,否则返回最新资源和 200 状态码;
- 弊端一,秒级精确度,如果客户端请求的时候,服务端在同一秒修改了文件很多次,客户端只拿到了其中一个版本并缓存了下来,结果可能让缓存不是最新的;
- 弊端二,Last-Modified 的改变不代表资源内容的改变,例如使用服务端使用编辑器打开某资源,也可能导致 Last-Modified 更新,结果导致客户端缓存失效。
Etag / If-None-Match:流程和 Last-Modifed/If-Modified-Since 一致;使用 Hash 判断资源是否被修改,因此不受秒级准确度限制,更精准。
缓存改进方案:md5 / hash 缓存和 CDN 缓存。
DNS Prefetch:打开后,浏览器提前将域名转为 IP 地址到浏览器 DNS 缓存中;<meta http-equiv="x-dns-prefetch-control" content="on"><link rel="dns-prefetch" href="//www.imooc.com">
不能被缓存的请求:
- HTTPS 请求;
- POST 请求;
- HTTP 响应头中不包含 Last-Modified/Etag,不包含 Cache-Control/Expires 的请求;
- HTTP 响应头中包含 Cache-Control:no-store(pragma:no-cache 不确定) 等告诉浏览器不用缓存的请求。
对经常更新的文件使用max-age
的问题:
- 请求时间不一致问题——如果资源之间时相互依赖的,而请求时并不一定同时请求,就会造成过期时间不一致,当其中某个文件进行了更新,就可能破坏原有的依赖,导致客户端出现错误;
- 缓存丢失问题——如果丢失了某个经常被更新的文件的缓存,就会重新获取最新的该文件版本,这时可能破坏原有的依赖,和其它资源的过期时间不一样了,同样导致客户端出现错误;
- 如果某个资源不依赖其它资源,尽管经常更新,也可以使用
max-age
来减轻服务端的负担。
问题:通过哪个字段反应第一次设置 max-age 的时间?
相关链接:
- Static File Caching——CRA 上介绍的 cache-control 缓存,当开启文件名哈希,为 index.html 不设置缓存,为静态资源设置缓存,例如 Cache-Control: max-age=31536000;
- js 浏览器缓存机制;
- 使用 HTTP 缓存避免不必要的网络请求——有一张使用 cache-control 的流程图;
- “What's the difference between Cache-Control: max-age=0 and no-cache?”——
max-age=0 和 no-cache
的区别; - 深入理解浏览器的缓存机制;
- Chrome memory cache vs disk cache——关于浏览器缓存的“memory cache”和“disk cache”;
- MDN-Pragma;
- Caching best practices & max-age gotchas—— max-age 最佳实践。
关于状态码 304:请求协商缓存的时候服务端返回 304;搜索引擎会频繁抓取经常更新的网站,所以 304 可能降低网站曝光率。
状态码 | 含义 |
---|---|
1xx | 告知请求的处理进度和情况 |
2xx | 成功 |
3xx | 表示需要进一步操作 |
4xx | 客户端错误 |
5xx | 服务端错误 |
相关链接:
- Http状态码301和302理解以及使用场景;
- 具有代表性的 HTTP 状态码;
- HTTP Cats——用猫表示状态码;
- HTTP 状态码速查大全。
关于 CORS(cross-origin resource sharing):
- Cross-origin Resource Sharing,跨域资源共享;
- 当浏览器检测到请求是跨域的时候,会判断这个请求是简单请求还是非简单请求,对于不同的类型,服务器会响应不同的结果;
- 简单请求:
- 请求方法只能是 HEAD、GET、POST;
- 头信息只能有 Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type,并且 Content-Type 的值只能是 application/x-www-form-urlencoded、multipart/form-data、text/plain;
- 浏览器发出简单请求的时候,会在头部添加字段 Origin,告诉服务器自己的协议、域名和端口号;
- 服务器会对简单请求作出回应,返回 3 个头部字段,分别是 Access-Control-Allow-Origin、Access-Control-Allow-Credentials(可选)和 Access-Control-Expose-Headers(可选)。
- 非简单请求:
- 发出非简答请求之前需要先发出预检请求,预检请求使用 OPTIONS 方法,预检请求会检查服务器支持的请求来源、请求动词以及请求头信息;
- 服务器对预检请求作出回应,返回 4 个头部字段,分别是 Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-Control-Allow-Credentials 和 Access-Control-Max-Age;
- 为了避免每一次非简单跨域请求都预检,就使用 Access-Control-Max-Age 字段来设置预检存活时长,在这一段时间里都不用额外发送预检请求。
- 如果跨域请求失败,需要使用 XMLHttpRequest 的 onerror 捕获;
- 如果跨域请求需要 cookie,服务端响应时要设置头信息“
Access-Control-Allow-Credentials: true
”,浏览器要设置 XMLHttpRequest 实例的 withCredentials 为 true,“var xhr = new XMLHttpRequest(); xhr.withCredentials = true;
”,如果要关闭,就设置为 false。
关闭 Chrome 的同源策略,允许跨域:
# MacOS (in Terminal)
open -na Google\ Chrome --args --user-data-dir=/tmp/temporary-chrome-profile-dir --disable-web-security --disable-site-isolation-trials
关于 jsonp:
function jsonp({ url, params, callback }) {
return new Promise(resolve => {
let script = document.createElement("script");
window[callback] = function(data) {
resolve(data);
document.body.removeChild(script);
};
params = { ...params, callback }; // wd=b&callback=show
let arrs = [];
for (let key in params) {
arrs.push(`${key}=${params[key]}`);
}
script.src = `${url}?${arrs.join("&")}`;
document.body.appendChild(script);
});
}
jsonp({
url: "http://localhost:3000/say",
params: { wd: "Iloveyou" },
callback: "show"
}).then(data => {
console.log(data);
});
相关链接:
- 跨域资源共享 CORS 详解——阮一峰的 CORS 教程;
- Disable-web-security in Chrome 48+——关闭同源策略。
53 端口,域名解析时 UDP,区域同步传输 TCP。
使用名称而不是域名来确定通信对象的网络:Windows 网络的原型 PC-Network。
向 DNS 服务器发送的消息中包含三种:域名、Class 和记录类型。
记录类型:
- A,Address;
- MX,Mail-Exchange,邮件交换;
- PTR,根据 IP 地址反查域名;
- CNAME,查询域名相关别名;
- NS,查询 DNS 服务器的 IP 地址;
- SOA,查询域名属性信息(P38)。
域名用点分隔每个域,一个域的信息作为一个整体放在 DNS 服务器中,一个域不会拆开放在多台 DNS 服务器中。
DNS 服务器有缓存功能。
相关链接:
CA 证书,443 端口,SSL 加密传输。
SSL 协议的握手过程:
第一步,爱丽丝给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。
第二步,鲍勃确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。
第三步,爱丽丝确认数字证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给鲍勃。
第四步,鲍勃使用自己的私钥,获取爱丽丝发来的随机数(即Premaster secret)。
第五步,爱丽丝和鲍勃根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程。
其中的协议版本号:94 年的 SSL 1.0,95 年的 SSL 2.0,96 年的 SSL 3.0,99 年的 TLS 1.0,06 年的 TLS 1.1,08 年的 TLS 1.2。
相关链接:
- SSL/TLS协议运行机制的概述——阮一峰教程;
- 图解SSL/TLS协议——阮一峰教程;
- HTTPS系列干货(一):HTTPS 原理详解——又拍云知乎教程。
MTU:Maximum Transmission Unit,最大传输单元。以太网中一般 1500 字节。
MSS:Maximum Segment Size,最大分段大小。MSS 减去 40 字节的 TCP 和 IP 头部大小,结果就是 MSS。也可以说一个网络包能容纳的最大数据长度就是 MSS。
|-----------MTU-----------|
报头/SFD MAC 头部 IP头部 TCP 头部 数据 FCS
|--MSS--|
SFD:Start Frame Delimiter,起始帧分界符。
FCS:
- Frame Check Sequence,帧校验序列;
- 用来检查传输过程中因噪声导致的波形紊乱,数据错误,长度为 32 比特;
- 计算公式相当于磁盘中使用的 CRC 错误校验码,Cyclic Redundancy check,循环冗余校验;
- 接收方计算的 FCS 和电信号里的 FCS 如果相同,代表数据正确。
Mac 系统使用netstat -rn
查看路由表。
MacOS 使用arp -a
查询 ARP 缓存。
MAC:Media Access Control(p115)。
网卡发送数据包电信号的时候,通过“时钟信号+数据信号”的方式叠加发送(10BASE-T 的方式),接收方通过报头找到时钟信号的发送频率后,再通过异或计算,就能求出数据信号。
PHY/MAU:
- Physical Layer Device,物理层装置,Medium Attachment Unit,介质连接单元;
- MAC 模块把数字信号转为电信号后,由称为 PHY 或 MAU 的信号收发模块发送出去;
- PHY/MAU 的功能是对 MAC 模块产生的信号进行格式转换,以支持网线的传输格式。
PnP:Plug and Play,即插即用(p124)。
相关链接:
- Mac 路由表相關筆記;
- 异或运算 XOR 教程——“可以理解为 XOR 是更单纯的 OR 运算”;
- 最多能创建多少个 TCP 连接?;
- 资深 Web 开发的经验之谈:为什么你开发的网页不应该大于 14KB?,将数据收发和延迟(数据往返距离)结合说明 14kb 的好处,速度不仅和带宽有关,也和延迟有关。
Get 请求的长度限制:由客户端和服务端决定,Chrome 限制 8182 比特,NGINX 默认限制 8k;IE 支持的长度最短,所以要兼容所有浏览器只要兼容 IE 就行了。
关于 http/2:
- SPDY 协议和 http/2;
- http/2 仍然是无状态的,但是引入了索引表,索引表存储了字段信息;
- 关于 http/2 的命名,因为标准不打算给 http 出小版本,因此没有小数点,下一个版本是 http/3.
关于 http/3:基于 UDP 实现了类似 TCP 的多路复用数据流、传输可靠性的功能,这套功能称为 QUIC 协议。
HTTP 的请求消息和响应消息:
<方法><空格><URI><空格><HTTP 版本>
<key>:<value>
...
...
<空行>
<body>
<HTTP 版本><空格><状态码><空格><响应短语>
<key>:<value>
...
...
<空行>
<body>
避免 HTTP/2 之前版本的 6 个 TCP 连接限制:多域名部署(域名分片)。
相关链接:
- HTTP 协议入门——阮一峰的 Http 教程;
- 跨域资源共享 CORS 详解——阮一峰的跨域资源共享教程;
- 正向代理与反向代理的区别;
- 一文读懂 HTTP/2 特性——又拍云知乎教程;
- 关于URL编码——阮一峰的 URL 编码文章。
相关链接:
- GET 和 POST 到底有什么区别?——知乎回答,对 GET POST 在浏览器和接口中的解释。
相关链接:
- SEO 谷歌文档;
- 搜索引擎优化—— ahrefs 的 SEO 教程;
- 发现了不错的 SEO 教程—— V2EX 关于 SEO 的帖子。
“返回私密数据的mask,XSS,CSRF,跨域安全,前端加密,钓鱼,salt,……”——GET 和 POST 到底有什么区别? - 大宽宽的回答 - 知乎 https://www.zhihu.com/question/28586791/answer/767316172
相关链接:
- 【白话科普】从“熊猫烧香”聊聊计算机病毒——又拍云在 Ruby 社区发布的系列文章。
关于 http 和 tcp 关系的问题:
应用程序收到组装好的原始数据,以浏览器为例,就会根据 HTTP 协议的Content-Length字段正确读出一段段的数据。这也意味着,一次 TCP 通信可以包括多个 HTTP 通信。——https://www.ruanyifeng.com/blog/2017/06/tcp-protocol.html
相关链接:
- 你猜一个 TCP 连接上面能发多少个 HTTP 请求;
- Edge 计时细分阶段说明——“已为此源打开六个 TCP 连接,这是限制。 仅适用于 HTTP/1.0 和 HTTP/1.1。”;
- TCP 协议简介——评论——“一次 TCP 通信包含多次 HTTP 通信,反之不成立。如果 HTTP 通信到一半, TCP 断了,就只能重新开始了。”
关于浏览器访问网站流程:解析URL > 缓存判断 > DNS > 获取 MAC 地址 > TCP 握手 > HTTPS 握手 > 响应 > 页面渲染 > 挥手
URL 的组成:协议 + 域名 + 端口 + 路径 + 文件 + 锚 + 参数
常见协议:HTTP、HTTPS、FTP、POP3、SMTP。
TCP 和 UDP 的场景:TCP 要准确度高的,如文件传输,UDP 视频、通话。
OSI 七层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
URL 的各种形式:
var url = "http://user:password@www.a.com:90/dir/file1.htm" // 用 HTTP 协议访问 Web 服务器
var url = "ftp://user:password@ftp.a.com:21/dir/file1.html"; // 用 FTP 协议下载和上传文件
var url = "file://localhost/C:/path/file1.zip"; // 读取客户端计算机本地文件
var url = "mailto:tone@a.com"; // 发送电子邮件
var url = "news:comp.protocols.tcp-ip"; // 阅读新闻组的文章
IP 地址有网络号和主机号,但是 32 比特的 IP 不能直接区分,所以使用子网掩码来区分,子网掩码为 1 的部分是网络号,0 的部分是主机号。IP 地址的主机号为 0 表示子网,为 1 表示对子网进行广播。
子网掩码的形式:
- 和 IP 格式相同,例如 255.255.255.0;
- 用比特数表示,例如 24(一个 255 占 8 比特,三个 255 就是 24 比特)。
端口号和 IP 地址一样都是由 IANA(Internet Assigned Number Authority,互联网编号管理局)来管理的。
客户端通过 http 发出请求,tcp 进行握手,建立连接,tcp 把数据拆分成数据包,再经过网络层,链路层,物理层,直到服务端,当服务端做出响应,返回给客户端的时候,tcp 再组装数据,最后 http 收到响应。
相关链接:
- Maximum URL length is 2,083 characters in Internet Explorer:IE GET 请求最长 2083 个字符;
- 传输控制协议——wiki;
- 以太网帧格式——wiki。
资料:
- 图解SSL/TLS协议
- 终于有人把正向代理和反向代理解释的明明白白了!
- DNS 查询原理详解
- HTTP Cats:用猫表示状态码。
- HTTP 状态码速查大全;
- MDN-HTTP 文档;
- 互联网协议入门(一)——阮一峰教程;
- 互联网协议入门(二)——阮一峰教程;
- HTTP 协议入门——阮一峰教程;
- TCP 协议简介——阮一峰教程;
- TCP协议疑难杂症全景解析——作者是阮一峰 ssl 教程中提到的对“3 个随机数生成会话密钥”问题进行解释的作者,dog250;
- HTTP/3 原理与实践——腾讯博客。
书籍:
相关链接:
- NGINX Max URL Length - 414 URI Too Large:NGINX 默认 8k url 长度;
- SSL延迟有多大?。