小白图解网络电子书-笔记一

161 阅读13分钟

1 边看

image.png 可以F12 点击网络 点击一个请求 查看对应的信息 URL是啥,就是统一资源定位符,是用来标识互联网上资源的地址

2 URL和URi的区别

URL 统一资源定位符,是URI的子集,URI是统一资源标识符

image.png

3 七个请求方法

GET请求指定的⻚⾯信息,并返回消息主体(body)+头信息(header)。 HEAD: HEAD和GET本质是⼀样的,区别在于HEAD只返回头信息(header),不返回消息主体(body)。⼤家不要以为它没⽤,它跟GET和POST⼀样,在http/1.0的时候就存在了,实属三元⽼之⼀了。主要⽤途如果想要判断某个资源是否存在,虽然⽤GET也能做到,但这⾥⽤HEAD还省下拿body的消耗,返回状态码200就是有404就是⽆如果请求的是⼀个⽐较⼤的资源,⽐如⼀个超⼤视频和⽂件,你只想知道它到底有多⼤,⽽不需要整个下载下来,这时候使⽤HEAD请求,返回的headers会带有⽂件的⼤⼩(contentlenght)。 PUT:这个⽅法⽐较少⻅。在HTTP规范中POST是⾮等幂的,多次调⽤会产⽣不同的结果。⽐如:创建⼀个⽤户,由于⽹络原因或是其他原因多创建了⼏次,那么将会有多个⽤户被创建。⽽PUT id/xiaobai则会创建⼀个id为xiaobai的⽤户,多次调⽤还是会创建的结果是⼀样的,所以PUT是等幂的。但是⼀般为了避免造成⼼智负担,实战中也会使⽤POST替代PUT。 DELETE: 一般可以使用POST代替删除 OPTIONS: 获取当前页面的方法,要是请求成功的话就是在http带上各种Allow的头,表示在某个请 Options堪称是⽹络协议中的⽼实⼈,就好像⽼实⼈刚谈了个⼥朋友,每次牵⼿前都要问下⼈家“我可以牵你的⼿吗?”,“我可以抱你吗?”,得到了答应后才会下⼿。差点被这⽼实⼈⽓质感动得留下了不争⽓的泪⽔。求对于的有啥方法

image.png

lg:一般在要跨域就是浏览器发起复杂请求前会自动发起OPTIONS请求

4 简单请求和复杂请求

4.1 不会触发CORS预检请求 4.2 方法是GET HEAD POST 4.3 只要Headers字段 Accept Accept-Language Content-Language Content-Type DPR/Downlink/Save-Data/Viewport-Width/Width(这些不常⻅,放在⼀起) 4.4 Content_Type只有下面三种 application/x-www-form-urlencoded multipart/form-data text/plain 4.5 请求任意对象XMLHttpRequestUpload 对象均没有注册任何事件监听器; 4.6 请求里面没有使用ReadableStream对象

5 复杂请求:不是简单请求的就是

6 跨域

同源:就是域名,协议,端口都相同

image.png 需要注意的是:localhost和127.0.0.1指向本机,但是也不是属于同源 非同源之间的网页调用就是跨域,在浏览器同源策略下的,向不同源的发送XHR请求,浏览器认为该请求不受信任,禁止请求

7 Status Code

状态码是什么? HTTP Status Code 就是HTTP状态码

image.png

200 ok 307 内部重定向 404 请求失败,没有在服务器上被发现 499 超时 502 服务器没办法给予正常的响应,一般是服务器崩溃 504 网关超时

8 Headers

Content_Length是消息的长度,十进制表现 1 如果小于实际长度就会截断 2 要是大的话就会导致请求一直阻塞,因为服务端会一直认为这次的body是长度是那个,剩下的还在路上捏

9 Range

HTTP Range Requests 协议就是要指定请求文件的起始位置和结束位置

10 Connection

长连接和短连接 10.1 Connection:close 就是响应完毕以后立马关闭链接 10.2 Connection:keep-alive 就可以继续响应下一个请求

image.png

Request Header⾥的Connection: keep-alive头是为了告诉服务端,客户端想要以⻓连接形式进⾏通信。⽽Response Header⾥的Connection: keep-alive头是服务端告诉客户端,我的服务器⽀持以⻓连接的⽅式进⾏通信。如果不能使⽤⻓连接,会返回Connection: close,相当于告诉客户端“我不⽀持⻓连接,你死了这条⼼,⽼⽼实实⽤短连接吧”。

为什么使用长连接? http建立在tcp的协议上,tcp的建立要三次握手,关闭要四次握手,就建立都要时间 可以看到,在使⽤Connection: close通信时,每次都需要重新经历⼀次握⼿挥⼿。可以通过Connection: keep-alive省下这部分的资源消耗。 ⻓连接可以省去较多的TCP建⽴和关闭的操作,减少浪费,节约时间。 可以设置空闲时间断开让服务端主动断掉

11 Cookies

是浏览器访问服务器,服务器传给浏览器的一段数据,里面带有浏览器的身份信息,浏览器要保存这段数据,不能随便删除,此后每次访问的时候带上这个数据,服务器使用这u但数据确认浏览器身份信息

作用: 1 识别用户身份 2 持久化用户信息

12 Referrer Policy 和Referrer

Referrer Policy是什么Referrer字段,会⽤来指定该请求是从哪个⻚⾯跳转⻚来的,⾥⾯的信息是浏览器填的。⽽Referrer Policy则是⽤于控制Referrer信息传不传、传哪些信息、在什么时候传的策略。 image.png

Referrer是什么Referrer是HTTP请求header的报⽂头,⽤于指明当前流量的来源参考⻚⾯,常被⽤于分析⽤户来源等信息。通过这个信息,我们可以知道访客是怎么来到当前⻚⾯的。⽐如在上⾯的请求截图⾥,可以看出我是使⽤www.bilibili.com/访问的视频资源。 image.png Referrer 是来源,policy是策略

13 Cache-control

image.png 用来控制浏览器缓存,浏览器缓存就是浏览器本地保存网站资源,下次就不用从服务器获取,但是不会永远保存,会限定保存的时间,这叫生存时间(TTL) 常见的策略 cache-control: private具有“private”指令的响应只能由客户端缓存,不能由中间代理(例如CDN或代理)缓存。这些资源通常是包含私密数据的资源,例如显示⽤户个⼈信息的⽹站。 cache-control: public相反,“public”指令表示资源可以由任何缓存存储。 cache-control: no-store带有“no-store”指令的响应⽆法缓存到任何位置,也永不缓存。也就是说,⽤户每次请求此数据时,都必须将请求发送到源站服务器以获取新副本。此指令通常保留给包含极其敏感数据的资源,例如银⾏帐户信息。 cache-control: max-age此指令指定了⽣存时间,也就是资源在下载后可以缓存多少秒钟。例如,如果将最⼤期限设置为1800,则⾸次从服务器请求资源后的1800秒(30分钟)内,后续请求都会向⽤户提供该资源的缓存版本。如果30分钟后⽤户再次请求资源,则客户端需要向服务器重新请求该资源。 cache-control: no-cache从⽹⻚截图⾥可以看出,使⽤的缓存控制指令是cache-control: no-cache。它表示,只有先检查资源没有更新版本后,才可使⽤所请求资源的缓存版本。那么问题来了,怎么判断资源是否有更新版本呢?这就需要ETag。

14 ETag

Entity tag 是服务端的一个资源版本的令牌标识,在响应头里传给客户端,每当资源更新时候,令牌就会更新 然后就是要是浏览器再次请求这个资源的时候,就会再把这个东西传递给服务端,服务端拿到以后就是RTAG就会对比资源是不是发生变化,要是未发生变化,就返回304 HTTP状态码,不返回具体资源,要是资源更新了,就会下载版本提供给用户

lg:就是比对是不是要更新啦

15 TCP沾包

image.png

每进入一层的时候都会多加一个报头,每多一个报头就会理解数据多带一个帽子 报头记录了消息从哪里来到哪里去,以及消息多长,比如mac头部记录的就是硬件的唯一地址,ip头记录就是从哪里来和到哪里去,传输层头记录的是到达主机以后具体去哪个进程,通过这些报头,信息在路由器之间流传,最后到达目的机器上,接收者再通过这些报头,一步一步的还原发送者最原始要发送的消息

image.png

16 为啥要数据切片

软件是属于应用层的,消息是进入使用的TCP协议 进入是切片变成一些数据包,数据包的长度是MSS

image.png

17 MTU和MSS的区别

image.png MTU最大传输单元,由网络接口层(数据链路层)提供给网络层,最大的一般是1500Byte ,要是大余的话就要分片了 MSS提交给Ip层的最大分段大小,MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte,如果应⽤层有2000 byte发送,那么需要两个切⽚才可以完成发送,第⼀个TCP切⽚= 1460,第⼆个TCP切⽚= 540。

18 什么是沾包

一个消息被错误的沾在了一起,导致出现问题

image.png

19 为啥会出现沾包?

Tcp Transmission Control Protocol。传输控制协议,是⼀种⾯向连接的、可靠的、基于字节流的传输层通信协议。

因为是使用字节流传递的方式,数据还可能被切割和组装成各种数据包,接受端没有正确的还原原本的信息就会出现沾包现象

20 为啥要组装发送的数据?

让小包变大包,防止浪费网络io ⽐如⼩⽩爸让⼩⽩出⻔给买⼀瓶酱油,⼩⽩出去买酱油回来了。⼩⽩妈⼜让⼩⽩出⻔买⼀瓶醋回来。⼩⽩前后结结实实跑了两趟,影响了打游戏的时间。优化的⽅法也⽐较简单。当⼩⽩爸让⼩⽩去买酱油的时候,⼩⽩先等待,继续打会游戏,这时候如果⼩⽩妈让⼩⽩买瓶醋回来,⼩⽩可以⼀次性带着两个需求出⻔,再把东⻄带回来。上⾯说的其实就是TCP的Nagle算法优化,⽬的是为了避免发送⼩的数据包。在Nagle算法开启的状态下,数据包在以下两个情况会被发送:如果包⻓度达到MSS(或含有Fin包),⽴刻发送,否则等待下⼀个包到来;如果下⼀包到来后两个包的总⻓度超过MSS的话,就会进⾏拆分发送;等待超时(⼀般为200ms),第⼀个包没到MSS⻓度,但是⼜迟迟等不到第⼆个包的到来,则⽴即发送。

问题就是包的组装问题等导致的沾包问题么?

21 关掉Nagle算法就不会沾包了么?

不组装的话,应用层一次性拿走数据也会发现沾包的现象,所以关闭也意义会发生沾包

22 怎么处理沾包?

根本原因是:不确定消息的边界,接收端在面对二进制流的时候不知道多少个01才算一个消息,所以只要使用发送消息带上识别信息边界的信息就可以识别区分 22.1 加入特殊标志

image.png 22.2 加入信息长度

image.png HTTP中的Content-Length就起了类似的作⽤,当接收端收到的消息⻓度⼩于Content-Length时,说明还有些消息没收到。那接收端会⼀直等,直到拿够了消息或超时

image.png

23 UDP会沾包么?

UDP,User Datagram Protocol。⽤户数据包协议,是⾯向⽆连接,不可靠的,基于数据报的传输层通信协议。 基于数据报是指⽆论应⽤层交给UDP多⻓的报⽂,UDP都照样发送,即⼀次发送⼀个报⽂。⾄于如果数据包太⻓,需要分⽚,那也是IP层的事情,⼤不了效率低⼀些。UDP对应⽤层交下来的报⽂,既不合并,也不拆分,⽽是保留这些报⽂的边界。⽽接收⽅在接收数据报的时候,也不会像⾯对TCP⽆穷⽆尽的⼆进制流那样不清楚啥时候能结束。正因为基于数据报和基于字节流的差异,TCP发送端发10次字节流数据,⽽这时候接收端可以分100次去取数据,每次取数据的⻓度可以根据处理能⼒作调整;但UDP发送端发了10次数据报,那接收端就要在10次收完,且发了多少,就取多少,确保每次都是⼀个完整的数据报。

image.png

image.png 23.1 tcp 的报头

image.png

image.png 跟UDP不同在于,TCP发送端在发的时候就不保证发的是⼀个完整的数据报,仅仅看成⼀连串⽆结构的字节流,这串字节流在接收端收到时哪怕知道⻓度也没⽤,因为它很可能只是某个完整消息的⼀部分。

24为啥长度字段冗余还要加到UDP首部中?

关于这⼀点,查了很多资料,《TCP-IP详解(卷2)》⾥说可能是因为要⽤于计算校验和。也有的说是因为UDP底层使⽤的可以不是IP协议,毕竟IP头⾥带了总⻓度,正好可以⽤于计算UDP数据的⻓度,万⼀UDP的底层不是IP层协议,⽽是其他⽹络层协议,就不能继续这么计算了。但我觉得,最重要的原因是,IP层是⽹络层的,⽽UDP是传输层的,到了传输层,数据包就已经不存在IP头信息了,那么此时的UDP数据会被放在UDP的Socket Buffer中。当应⽤层来不及取这个UDP数据报,那么两个数据报在数据层⾯其实都是⼀堆01串。此时读取第⼀个数据报的时候,会先读取到UDP头部,如果这时候UDP头不含UDP⻓度信息,那么应⽤层应该取多少数据才算完整的⼀个数据报呢?

25ip层有沾包么

IP层会对⼤包进⾏切⽚,是不是也有粘包问题?先说结论,不会。⾸先前⽂提到了,粘包其实是由于使⽤者⽆法正确区分消息边界导致的⼀个问题。先看看IP层的切⽚分包是怎么回事。

image.png 25.1 总结 粘包这个问题的根因是由于开发⼈员没有正确理解TCP⾯向字节流的数据传输⽅式,本身并不是TCP的问题,是开发者的问题。 TCP不管发送端要发什么,都基于字节流把数据发到接收端。这个字节流⾥可能包含上⼀次想要发的数据的部分信息。接收端根据需要在消息⾥加上识别消息边界的信息。不加就可能出现粘包问题 。TCP粘包跟Nagle算法有关系,但关闭Nagle算法并不解决粘包问题。 UDP是基于数据报的传输协议,不会有粘包问题。 IP层也切⽚,但是因为不关⼼消息⾥有啥,因此有不会有粘包问题。切片就算了,还会带有在包里的位置(offset)和ip头部消息 ,最后怎么会错误捏 TCP发送端可以发10次字节流数据,接收端可以分100次去取; UDP发送端发了10次数据报,那接收端就要在10次收完。数据包也只是按着TCP的⽅式进⾏组装和拆分,如果数据包有错,那数据包也只是犯了每个数据包都会犯的错⽽已。