Skip to content

Latest commit

 

History

History
379 lines (278 loc) · 22.2 KB

阅读《网络是怎样连接的》记录.md

File metadata and controls

379 lines (278 loc) · 22.2 KB

阅读《网络是怎样连接的》记录

{{TOC}}

网络知识是计算机的基础,是作为计算机从业者的基本素养。下面的内容是我阅读《网络是怎样连接的》的记录合了,也结网络进行了一些扩展。

连接和断开

keep-alive

缓存

强制缓存:直接从客户端本地获取,不向服务端请求,即使断网也能获取;这种情况下,状态码 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 的时间?

相关链接:

状态码

关于状态码 304:请求协商缓存的时候服务端返回 304;搜索引擎会频繁抓取经常更新的网站,所以 304 可能降低网站曝光率。

状态码 含义
1xx 告知请求的处理进度和情况
2xx 成功
3xx 表示需要进一步操作
4xx 客户端错误
5xx 服务端错误

相关链接:

跨域

关于 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);
});

相关链接:

DNS(Domain Name System)

53 端口,域名解析时 UDP,区域同步传输 TCP。

使用名称而不是域名来确定通信对象的网络:Windows 网络的原型 PC-Network。

向 DNS 服务器发送的消息中包含三种:域名、Class 和记录类型。

记录类型:

  • A,Address;
  • MX,Mail-Exchange,邮件交换;
  • PTR,根据 IP 地址反查域名;
  • CNAME,查询域名相关别名;
  • NS,查询 DNS 服务器的 IP 地址;
  • SOA,查询域名属性信息(P38)。

域名用点分隔每个域,一个域的信息作为一个整体放在 DNS 服务器中,一个域不会拆开放在多台 DNS 服务器中。

DNS 服务器有缓存功能。

相关链接:

HTTPS

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。

相关链接:

数据收发

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)。

相关链接:

HTTP

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 方法

相关链接:

SEO

相关链接:

安全

“返回私密数据的mask,XSS,CSRF,跨域安全,前端加密,钓鱼,salt,……”——GET 和 POST 到底有什么区别? - 大宽宽的回答 - 知乎 https://www.zhihu.com/question/28586791/answer/767316172

相关链接:

问题

关于 http 和 tcp 关系的问题:

应用程序收到组装好的原始数据,以浏览器为例,就会根据 HTTP 协议的Content-Length字段正确读出一段段的数据。这也意味着,一次 TCP 通信可以包括多个 HTTP 通信。——https://www.ruanyifeng.com/blog/2017/06/tcp-protocol.html

相关链接:

其它

关于浏览器访问网站流程:解析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 收到响应。

相关链接:

引用

资料:

书籍:

相关链接: