HTTP:超文本传输协议,是应用层的一个协议,定义了超文本的传输的标准。
HTTPS:是HTTP的一种,以安全为重点的HTTP,在HTTP的基础上加入了SSL,因此可以看作HTTPS = HTTP + SSL。HTTPS的安全基础是SSL,通过SSL进行传输加密与身份认证,保证了传输过程的安全性。
通俗点说,HTTP就是说话的语言、语法,规定了我们要怎么说话,以及说话时语句怎么组成。而HTTPS则相当于暗语,只有说话者和目标者知道并能听懂。
为了让两个相互通信的计算机系统能够高度协调工作,设计者使用了‘分层’的方法将这一复杂困难的问题转化为了若干小问题。计算机网络体系结构就这样诞生了。计算机网络体系结构有OSI体系结构、TCP/IP体系结构、还有为了便于教学计算机网络原理而产生的五层协议的体系结构。
OSI/RM标准,中文名称是开放系统互连基本参考模型。是由ISO国际标准化组织提出的国际标准。但是由于制定该标准时,制定的专家、学者多为原先电信网络的专家、学者,仍秉持着电信网络的理念来设计标准,并且缺乏互联网的实际经验,导致OSI标准缺乏商业驱动力,并且实行起来过于复杂,运行效率低下。并且因为在设计时过多的追求完善,导致OSI标准制定之后,市场已被使用TCP/IP协议的互联网抢占,无法及时进入市场,导致OSI/RM标准仅仅只是ISO认可的法律上的国际标准,而非事实上的国际标准。
与OSI/RM标准邀请一大堆专家学者参与制定标准相反,TCP/IP协议是由企业提出,并在发展中一步步完善的,与OSI/RM标准相比,TCP/IP标准更加简洁,商业气息更加浓厚,更为适合互联网的环境,并且因为TCP/IP的早早提出,使得TCP/IP协议成为了实际上的国际标准。
需要注意的是,虽然TCP/IP协议名义上有四层结构,但是最下层的链路层并没有属于TCP/IP体系的具体协议,因此,TCP/IP实质上只有最上面的三层。为了方便阐述计算机网络原理(并非新发展的一种体系结构),综合OSI和TCP/IP的优点,提出了五层协议的体系结构(实际使用仍使用TCP/IP协议)。
以上三种类型的计算机网络体系结构图如下
TCP/IP协议,并不仅仅指的是TCP协议和IP协议两个协议,而是以这两个协议为中心,围绕着这两个协议的许多协议组成的协议簇。
TCP协议,即传输控制协议,与用户数据报协议UDP同为传输层的协议。TCP协议与UDP协议的区别在于TCP协议是一个面向连接的、可靠的、基于字节流的协议,而UDP则是面向无连接的协议。面向连接指的是客户端与服务器之间的连接,在TCP协议下,客户端与服务器简历连接之前需要进行三次握手,确保客户端与服务器都拥有发送与接收的能力。不仅如此,TCP还会记录数据发送的情况,避免因为丢包或网络问题导致数据接收不到。因此TCP是有状态的、可控的,而UDP是无状态的、不可控的。面向字节流是TCP为了维护状态,在数据传输中将IP包变成了字节流,而UDP则是基于数据的。由于TCP有状态且可控,相较于UDP更为安全,因此HTTP协议使用TCP协议做为通讯协议。
IP协议的英文全称为Internet Protocol,即网际互联协议,他解决了通信双方寻址的问题,相当于给每一台计算机配备了一个编号,通过这个编号来辨别不同的计算机。
SYN:同步序列编号。
初始双方处于ESTABLISHED状态,此时用户端向服务端发送FIN报文,序列号为seq=u,用户端进入FIN-WAIT-1状态。服务器端接收到之后,进入CLOSED-WAIT状态。并向用户端发送ACK报文,ack=u+1。用户端接收到报文后,进入FIN-WAIT-2状态.随后服务器端向用户端发送FIN、ACK报文,seq=n,ack=u+1.之后服务器端进入LAST-ACK状态。用户端接收到之后,向服务器端发送ACK报文,ack=n+1,之后进入TIME-WAIT状态等待2MSL,确定不会再接收到来自服务器端的信息,进入CLOSED状态。服务器端接收到ACK报文后,进入CLOSED状态。
为什么会有TIME-WAIT状态:确定没有后续的来自服务器端的包,避免数据包混乱。
等待2MSL:1 个 MSL 确保四次挥手中主动关闭方最后的 ACK 报文最终能达到对端;1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报文可以到达。
URI是统一资源标识符,URL是统一资源定位符,我们常常说的网址就是URL。URI由URL与URN(统一资源名称)组成。
由于URI在网上任意位置都能访问到.因此,HTTP协议使用URI定位网上的资源.
首先,我们需要知道浏览器是多进程的,每当我们点开一个页面,浏览器都会使用系统分配的cpu、内存等资源,开启一个新的进程,因此,我们可以得知,每一个页面,都是一个独立的浏览器进程,这一进程就是浏览器渲染进程,也叫做Renderer进程,是浏览器的内核,具有页面渲染,脚本执行,事件处理等功能,对于我们前端来说,是浏览器最重要的进程。
(1)主进程,也叫做Browser进程,作用如下
(2)第三方插件进程:每种类型的插件都对应一个进程,仅当使用某个插件的时候才创建。
(3)GPU进程:用于进行3D绘制
为了避免因为某一个页面的崩溃或者某一个插件的问题而导致卡死,致使其他页面也受到影响。
(1)GUI 渲染线程
(2)JS 引擎线程
(3)定时器触发线程
setInterval与setTimeout所在的线程,由于JS引擎线程是单线程,但是又不能因为定时器而妨碍后续代码解析(这样会导致js运行时间过长,不仅仅无法达到预期中使用定时器的效果,还会因为js引擎线程与GUI线程的互斥,导致页面渲染加载堵塞),因此单独使用这个线程进行定时器的计时。
(4)浏览器事件线程
(5)http 异步线程
为了避免当GUI线程渲染完某一部分时,js引擎线程将已渲染那部分的某个数据进行修改,导致需要重新渲染或者出现不可预期的错误,因此浏览器设置两个线程互斥。
JS 任务分为同步任务和异步任务两种,同步任务都在JS引擎线程上执行,形成一个执行栈。异步任务往往占用资源多且耗时久,会进入事件列表并注册函数,当满足异步任务的条件时,将回调事件放入任务队列中。当执行栈中所有的同步任务执行完毕后,此时JS引擎线程空闲,系统会读取任务队列,将可运行的异步任务回调事件添加到执行栈中,开始执行。
微任务和宏任务皆为异步任务,它们都属于一个队列,主要区别在于他们的执行顺序,Event Loop的走向和取值。
宏任务:主代码块,setTimeout,setInterval等。
微任务:Promise,process.nextTick等。
首先会从任务队列中获取一个宏任务执行,执行过程中产生的微任务放入微任务的任务队列中,每当一个宏任务执行完毕后,事件循环都会先查询任务队列中是否有微任务存在,如果有,将所有微任务执行完毕之后,开始检查渲染,由GUI线程接管(避免因js任务队列过多而导致页面渲染加载堵塞,产生不可预期的后果),如果没有,直接开始检查渲染,由GUI线程接管。当渲染完毕之后,执行下一个宏任务。
我们以下面这条网址为例
https://search.bilibili.com/all?keyword=HTTP&from_source=webtop_search
当浏览器获取到服务器的 IP 地址后,浏览器会用一个随机的端口向服务器端口发起 TCP 连接请求,如果是HTTP,则是80端口,如果是HTTPS,是443端口。这个连接请求到达服务端后,通过 TCP 三次握手,建立 TCP 的连接。
TCP链接建立后,倘若使用的是HTTP协议,就可以直接进行数据传输了,但是倘若使用的是HTTPS,则还需要多进行TLS协商这一步操作,来在两个通信应用程序之间提供保密性和数据完整性。
浏览器到web服务器的连接建立后,浏览器会发送一个初始的 HTTP GET 请求,请求目标通常是一个 HTML 文件。服务器收到请求后,将发回一个 HTTP 响应报文,内容包括相关响应头和 HTML 正文。
TCP四次挥手断开连接。
浏览器根据获取到的数据,进行解析和绘制,大致流程如下:
构建DOM树:解析HTML语法,然后解析成DOM树,树由dom元素及属性节点组成,树的根是document对象。
构建CSS规则树:生成CSS规则树
构建render树:Web浏览器将DOM和CSSOM结合,并构建出渲染树(render tree)
布局:计算出每个节点在屏幕中的位置
绘制:即遍历render树,并使用UI后端层绘制每个节点。
浏览器将各层信息发送给GPU进程,GPU将各层合成,在屏幕上显示。
js引擎解析js文件,执行js代码。
DNS解析的作用是将网址自动转换成IP地址来进行通信,例如在对www.baidu.com进行DNS解析时,会将其解析为www(三级域名),baidu(二级域名),com(顶级域名)这三个域名。上述案例中的search.bilibili.com,解析完成之后,就变成了search(查询,三级域名),bilibili(哔哩哔哩,二级域名),com(工商企业,顶级域名)。该案例之所以没有www,是因为哔哩哔哩在申请域名的时候提交了不带www的解析方案,因此可以不加www。具体的DNS解析过程,如前文所述。
重绘(repaint或redraw):重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
重排(重构/回流/reflow):当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建, 这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。
重绘和重排的关系:在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。
重排必定会引发重绘,但重绘不一定会引发重排。
触发重排的条件:
优化方案:
http请求报文由请求行,消息头部、空行、请求正文四个部分组成。
GET /api/ tooltip/ query.list.do HTTP/2
其中GET是请求方法,/api/ tooltip/ query.list.do是URL,HTTP/2是HTTP协议版本。
Host:请求的主机名
User-Agent: 发出请求的浏览器类型
Accept: 客户端可识别的内容类型
Accept-Language: 浏览器想要获取的数据的语言类型
Accept- Encoding:浏览器支持的编码类型
Connection:浏览器告诉服务器是持久连接还是非持久连接
常用的HTTP请求方法有如下几种
http响应报文由状态行、响应头、空行和响应体四个部分组成。响应报文大致如下。
HTTP/2 200 OK
date: Thu, 01 Sep 2022 02:23:36 GMT
content-type: text/html; charset=utf-8
gear: 1
data: wss://*.bilibili.com:* *.bilibili.com *.hdslb.com *.biliapi.net *.biliapi.com; frame-ancestors 'self' *.bilibili.com *.biligame.com; report-uri https://security.bilibili.com/csp_report
expires: Thu, 01 Sep 2022 02:23:35 GMT
cache-control: no-cache
x-cache-webcdn: BYPASS from blzone01
content-encoding: br
X-Firefox-Spdy: h2
状态码开头为1,即状态码为1XX,表示请求已接收,继续处理。
100 Continue 继续。客户端应继续其请求。
101 Switching Protocols: 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议。
状态码开头为2,表示请求已被成功接受,处理。
200 OK:客户端请求成功。
201 Created:已创建,成功请求并创建了新的资源。
204 No Content:无内容。服务器成功处理,但未返回内容。一般用在只是客户端向服务器发送信息,而服务器不用向客户端返回什么信息的情况。不会刷新页面。
206 Partial Content:服务器已经完成了部分GET请求。
状态码开头为3,表示重定向。
301 Moved Permanently:永久重定向,表示请求的资源已经永久的搬到了其他位置302 Found:临时重定向,表示请求的资源临时搬到了其他位置
303 See Other:临时重定向,应使用GET定向获取请求资源。
304 Not Modified:表示客户端发送附带条件的请求时,条件不满足。返回304时,不包含任何响应主体。
307 Temporary Redirect:临时重定向。
状态码开头为4,表示客户端请求有误。
400 Bad Request:客户端请求有语法错误,服务器无法理解。
401 Unauthorized:请求未经授权,此时需要进行认证。
403 Forbidden:服务器收到请求,但是拒绝提供服务。
404 Not Found:请求资源不存在。
405 Method Not Allowed: 客户端请求中的方法被禁止。
407 Proxy Authentication Required:与401类似,请求要求代理的身份认证,请求者应当使用代理进行授权。
413 Precondition Failed:请求实体过大,服务器无法处理。常常在多文件上传或大文件上传中遇到。
415 Unsupported media type:不支持的媒体类型。
状态码开头为5,表示服务器端错误,服务器未能实现合法的请求。
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理
Date标头:消息产生的时间
Age标头:(从最初创建开始)响应持续时间
Server标头: 向客户端标明服务器程序名称和版本
ETage标头:不透明验证者
Location标头:URL备用的位置
Content-Length标头:实体的长度
Content-Tyep标头:实体的媒体类型
由于同源策略,浏览器对JS实施了安全限制,只要协议,域名,端口任何一个不同,都会被当作不同的域.导致LocalStorage,SessionStorage,Cookie等浏览器内存无法跨域访问.Dom节点无法跨域操作、Ajax无法跨域请求.
1.JSONP:由于script标签的src,img标签的src,link标签的href并不会被同源策略所限制,JSONP就借用了script标签的src,实现了跨域获取数据。JSONP是一个相对古老的解决跨域的方案,仅支持GET请求,需要前端后端共同实现。
2.WebSocket:由于设计原因,WebSock不附属于同源策略,它的跨域检测工作由服务端检测,服务器根据浏览器加上的Origin跨域请求头,判断此次WebSock是否合法.
3.Cors:跨域资源共享,需要由后端开启,开启后前端可跨域请求后端.
4.Node正向代理,利用服务端请求不会跨域的特性,让接口和当前站点同域,绕开同源策略.
5.Nginx反向代理,同Node代理相同,但是是由我们自己搭建一个中间服务.想要使用Nginx代理,我们需要下载Nginx.
6.window.postMessage,提供了一种受控机制,实现不同页面之间的数据传递.通常使用它进行页面和其打开的新窗口进行数据传递,多窗口之间的消息传递,页面于嵌套的iframe消息传递.
HTTP缓存策略有强缓存和协商缓存两种.
在HTTP1.0版本里,强缓存使用的是Expires字段,HTTP1.1使用的是Cache-Control字段.
Expires是用于表示资源的过期时间的请求头字段,值是一个绝对时间,是由服务器端返回的。在这个过期时间之前可以直接从缓存里面获取数据,无需再次请求。由于expires是根据本地时间来判断的,倘若客户端和服务器时间不同,会导致缓存命中误差,因此在HTTP1.1版本中,提出了一个新的字段----Cache-Control.
Cache-Control字段优先级高于Expires,在他的响应属性值max-age秒内,不与浏览器请求新的数据.倘若缓存数据失效,代表没有命中强缓存,进入协商缓存.
max-age:单位为秒,作用是设置缓存的存在时间,相对于发送请求的时间。只有响应报文首部设置Cache-control为非0的max-age或者设置了大于请求日期的Expires才有可能命中强缓存。当满足这个条件,同时响应报文首部中Cache-control不存在no-cache、no-store且请求报文首部不存在Pragma字段,才会真正命中强缓存。
no-cache:请求必须先行确定缓存的有效性。
no-store:表示禁止浏览器以及所有中间缓存存储任何版本的返回响应。
public:表明响应可以被浏览器、CDN等等缓存。
private:表明响应只作为私有的缓存,不能被CDN等缓存。
Last-Modified
Last-Modified是最后修改时间,在浏览器第一次给服务器发送请求后,服务器会在响应头中加上这个字段。如果再次请求,浏览器会在请求头中添加If-Modified-Since字段,如果该字段小于Last-Modified,则更新缓存,否则返回304,让浏览器直接使用缓存.
ETag
ETag是服务器根据当前文件的内容,对文件生成唯一的标识,服务器获取到标识的时候,与浏览器上的资源的ETag对比,如果改变,返回新值,没改变,返回304,让浏览器使用缓存.