web开发基础
web开发的两种模式
服务器渲染的开发模式(前后端不分离)
服务器端渲染的开发模式,就是由**服务器发送给客户端HTML页面
,页面是由服务器端把页面结构和数据动态拼接
**而成的。
优点
1.前端页面可以**快速渲染、首屏加载速度快
**。因为页面是由后端动态生成的HTML,浏览器直接渲染页面即可。对于移动端来说,还有省电的好处。
2.有利于网站**SEO优化
**。因为页面的HTML内容全部由服务器端生成,有利于搜索引擎爬虫获取信息,使网站易于被检索,提高网站曝光度。
缺点
1.占用服务器端资源
。
2.前后端混合开发,降低开发效率
。
前后端分离的开发模式
前后端分离开发依赖于ajax技术的广泛应用。前后端分离指:前端专注于页面ui的构建,使用ajax技术调用接口获取后端数据进行渲染。而后端只需要编写接口,返回数据供前端渲染
。
优点
1.开发效率高
。前端着重页面开发,后端着重接口开发。
2.减少服务器压力
。因为页面静态内容不再由服务器端返回。
3.用户体验好
。
缺点
1.不利于SEO优化
。完成的HTML页面在客户端生成,不利于爬虫爬取页面有效信息,导致网站不易被检索,无法提高曝光率。(解决方案:Vue、React等框架的**SSR技术
**可以解决前后端分离项目不利于SEO优化的问题。)
开发模式的选择
1.企业网站等主要**用于展示而没有复杂交互
,且需要达到易于被搜索的目的(SEO优化
)的网站,可以考虑服务器端渲染
**。
2.管理项目等**交互性强且不需要考虑SEO优化
的web项目可以考虑前后端分离
**。
3.**首屏渲染采用服务器端渲染+其他页面前后端开发
**的模式也是不错的选择。这样可以解决首屏渲染速度慢同时兼顾开发效率,也可以一定程度有利于SEO优化。
身份认证技术
jwt令牌
jwt令牌常用于**前后端分离项目的身份认证
**
原理
1.jwt令牌是一个由三部分字符串组成的长字符串,每一部分用符号"."分隔:Header(头部)
+Payload(负载)
+Signature(签名)
2.原始**Header
是一个JSON对象,一般存储着签名算法(默认是HS256)和令牌类型(默认JWT)
**。
3.原始**Payload
也是一个JSON对象,存储着真正要传递的数据
**,尽量不要存放隐私数据。
4.Signature则是对这条token的认证
。首先指定一个密匙(secret,只有服务器知道),然后把Header、Payload和Secret结合使用Header指定的签名算法,得到一个签名,然后将Header、Payload和Signature结合产生一个完整的jwt令牌。
产生签名的公式
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
此时的jwt由原始header+原始Payload+Signature组成,因为jwt不会对Header和Payload进行加密。
5.在用户登陆成功之后,会为用户发放jwt令牌,用户接收到jwt后,以后每次请求都需要携带jwt进行认证(一般**存放在请求头的Authorization字段
**),而服务器端会验证jwt的合法性,验证合法后,允许服务器响应用户请求。
注意点
1.JWT的设计初衷是轻量级和易于传输,因此默认不加密,传递隐私数据建议加密。
2.为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,最好使用 HTTPS 协议传输。
3.JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
4.JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
session-cookie技术
session-cookie技术常用于**服务器端渲染的项目
**。
原理
1.session是一个由服务器端维护的存储空间,用户与服务器建立联系之后,会由服务器为其**分发唯一的sessionID
(通过响应头的Set-Cookie字段发送给客户端)。这个sessionID在服务器端对应一个session存储空间,这个存储空间保存用户的相关信息
。而在客户端,这个sessionID以及相关信息存储在浏览器中,被称为cookie
。当用户登录服务器之后,此后每一次请求都会携带cookie,当cookie验证成功后,服务器会根据cookie寻找到对应的session存储空间,读取存储的用户信息
**,完成用户的身份认证。
服务端推送技术
轮询
轮询就是在客户端浏览器设置一个**发送请求的定时器
,定时器每隔一定时间就发送一次请求,询问服务器端是否有新数据,如果有新数据就返回。没有就返回空数据。缺点
是浏览器每次都会发出请求,间隔短且有可能都是无效请求,浪费大量的服务器资源
。消息的推送有延迟
**。
长轮询
长轮询是对轮询的一种优化。当服务器端接收到请求时,如果没有需要推送的消息,将会**阻塞这次请求,直到有消息推送或请求达到超时时间
**。相比于轮询,长轮询减轻了服务器压力,但还是存在服务器资源浪费。
SSE(Server-Send Events)
SSE利用的是当服务器向客户端**发送流数据时,客户端不会关闭连接
**,而是一直等待服务器端发送的流数据的机制。
webSocket
webSocket是一种**基于TCP的传输协议
。它允许客户端和服务器端之间用一次握手建立可以双向传输的全双工通信
**。
当客户端**第一次发送请求时
,会在请求头中,携带一些信息。告诉服务器端需要将通信协议升级
**为webSockert。当服务器端接收到请求后,会看自身是否支持webSocket的协议。如果支持会在本次响应的响应头中携带信息,告诉服务器端协议升级成功,以后采用webSocket协议通信。
http
http是一种用于**C/S端(client/server)通信协议
**,是基于TCP的协议。在通信过程中总是由C端发起请求,S端只能去回应C端的请求,而不能主动去发送数据给C端。双端之间的数据交换以独立的消息(而非数据流)进行通信。
http的报文
请求报
文
请求报文由**请求方式+请求资源的路径+http协议版本+请求标头+请求体
**组成。
empty line表示请求的元数据已经发送完毕。
响应报文
请求报文由**http协议版本+响应状态码+状态信息+响应标头+响应数据
**组成。
http的特性
http的拓展
标头的存在让http的功能易于拓展,只要C端和S端对标头的新语义进行了经过简单协商,新功能就可以被加入进来。
http的无状态
在同一个连接中,两个执行成功的请求之间是没有关系的。这就带来了一个问题,用户没有办法在同一个网站中进行连贯的交互。比如上一次请求,S端验证了我的身份信息,但是这次请求时,S端不会知道是谁发送请求给他,也就无法返回对应的数据给C端。但借助Cookie 就可使用有状态的会话。利用标头的扩展性,将其加入http请求的请求头,每个请求之间就能够创建会话,让每个请求都能共享相同的上下文信息或相同的状态。
一个完整的http请求流程
- http是一个基于TCP的协议,在通信之前,需要通过TCP的三次握手建立连接。
- C端发送http请求并等待S端响应。
- S端接收到请求并响应请求,等待下一次请求。
MIME 类型(IANA 媒体类型)
媒体类型定义了C端和S端应该以何种方式去解析响应或者请求中携带的数据。通过标头中的Content-type可以指定mim类型,如果不指定mime类型,可能会导致C|S端错误解析传递的数据。
http缓存
http缓存是一种http服务优化的技术,它可以**提高Web页面加载速度和减轻服务器负载
**。通过这种机制,Web浏览器或其他客户端可以存储先前获取的Web资源的副本,并在后续请求相同资源时使用这些副本,而不是再次从服务器请求。
缓存的工作流程
HTTP缓存运行主要依赖服务端设置Cache-Control
、Etag
、Age
、Expires
以及Vary
等响应标头来指定相应的缓存策略,客户端通过自动携带If-Modified-Since
、 If-None-Match
等请求标头来验证缓存的有效性。由于客户端的相关请求标头都是自动携带的,因此缓存的配置通常只发生在服务端
,具体工作流程如下:
http的重定向
http的重定向是一种为网站或页面提供多个可访问URL的技术。使用重定向我们实现网站无法提供服务期间的临时重定向、网站域名更换之后的永久重定向。
原理
重定向的主导权在S端,当C端发出请求后,S端在处理请求时,发现这次请求需要进行重定向,会返回一个3开头的状态码,以及在响应表头中加入一个Location字段,表示实际请求的URL,C端在接收到重定向时,它们会立刻加载 Location
标头中提供的新 URL。
http的条件请求
在条件请求中,请求的结果,甚至请求成功的状态,都会随着验证器与受影响资源的比较结果的变化而变化。
基本原理
当我们在http的表头中添加了代表**条件首部
的字段后,请求就会自动触发条件验证。这些首部规定了请求的前置条件,请求结果则视条件匹配与否而有所不同
**。条件首部包括If-Match
、If-None-Match
、If-Modified-Since
、If-Unmodified-Since
、If-Range
。
应用场景
验证缓存有效性
:但我们某个http请求采用了缓存来优化性能时,每当我们再次请求资源时需要**判断本地缓存是否有效
。此时可以使用条件请求,我们在标头携带上条件首部If-Modified-Since
**,它标识着资源最后的修改时间。如果服务器验证If-Modified-Since后,发现资源已经被修改了,那么这次请求就会携带上最新的资源,否则告诉C端直接使用缓存的资源。
http的范围请求
带有Range标头的http请求**允许服务器仅向其回传HTTP消息的一部分
**。范围请求对于支持随机访问的媒体播放器、明确只需大型文件某部分的数据处理工具,以及允许用户暂停及恢复下载的下载管理器等客户端尤其有用。
内容协商机制
内容协商机制是一种C端获取想要资源指定格式的机制。在服务器端,一个URL可能对应一个资源不同文件格式,那么服务器需要得知C端需要的是那种格式,此时就需要进行内容协商了。
两种内容协商机制的实现方法
- 客户端设置**
特定的HTTP标头
(又称为服务端驱动型内容协商或者主动内容协商),这是进行内容协商的标准方式
**。即C端在发送请求,指定需要什么格式的资源,这样S端可以直接返回C端需要的数据。 - 服务器返回
300
(Multiple Choices)或者406
(Not Acceptable)、415
(Unsupported Media Type)HTTP 响应状态码 (又称为代理驱动型协商或者响应式协商),这种方式一般用作备选方案。在这种协商机制中,当面临不明确的请求时,服务器会返回一个页面,其中包含了可供选择的资源的链接。资源呈现给用户,由用户做出选择。
http1.x的连接管理
早期http请求连接**采用次抛的形式(短链接)
**,当建立TCP连接完成这一次请求后,就会断开这次TCP连接。这样导致结果就是效率底下,也没有发挥TCP连接的优势(冷链接与热链接)。
在1.x版本中,http拥有了额外的两种连接方式,长链接和流水线。
长链接(主流连接方式)
一个长连接会保持一段时间,重复用于发送一系列请求,节省了新建 TCP 连接握手的时间,还可以利用 TCP 的性能增强能力。当然这个连接也不会一直保留着,连接在空闲一段时间后会被关闭,服务器可以使用 Keep-Alive
协议头来指定一个最小的连接保持时间)。
长链接的缺点:连接一直保持对于服务器是一种性能消耗;在重负载时,还有可能遭受 DoS 攻击。因此对于空闲的长链接应该即时关闭。
流水线
流水线在长链接基础上,允许客户端允许连续发送请求而不必等待上一次请求的响应。
TCP
握手
第一次:在客户端发出请求建立TCP连接,会**先发送一个SYN包(第一次握手)+seq(a)序列
**(用于标识这条SYN包请求)报文,告诉服务端我需要同步数据。
第二次:当服务端收到SYN包和seq序列后,会**返回一个包含SYN包+Ack包(Ack包包含seq(b)序列+确认号(seq(a)+1))的报文给客户端
**。其中SYN包+Ack包表示服务器同意了建立TCP连接,seq(b)序列(用于标识服务器这条SYN包请求),而确认号等于第一次客户端的seq+1则是为了方便客户端确认这次请求是针对第一次握手的响应。
第三次:最后,客户端发送带有**Ack包(seq1(a+1)+seq2(b+1))
**的报文给服务器。seq1等于第一次seqa+1是为了告诉服务器,这是哪一个TCP连接,seq2等于第二次seqb+1,则是为了告诉服务器端我接收到了你的确认信息。
挥手
断开连接时,客户端和服务端都能发起断开请求
。现在假设客户端的数据和请求已经发送完毕,发出了断开TCP连接的请求。
第一次:客户端首先**发送带有Ack包和Fin包的报文
,告诉服务器端我需要关闭TCP连接,然后进入close_wait_1阶段
**,等待服务端的第一次确认。
第二次:服务器端接收到断开请求后会**响应一个Ack包报文
,表示服务器端接收到了客户端的断开连接请求(客户端不会响应,客户端进入close_wait_2阶段
)。然后服务器进入close_wait阶段,等待己方还未发送完的数据发送完毕
**。
第三次:当服务器端的**数据发送完毕,或者close_wait时间到
,服务器端也会发送一个Fin包+Ack包的报文,然后进入last_ack阶段
**。当客户端接收服务器端的Fin包+Ack包时,就可以确认双方不会再有其他数据的发送了。
第四次:客户端发送最后一个Ack包报文,表示确认断开
。服务器端接收到客户端的最后一次确认之后,断开连接,而客户端进入time_wait阶段。当time_wait时间到且没有接收其他报文,证明服务器端已经正常关闭,自己最终关闭连接。
为什么握手只需要三次,挥手却需要四次?
主要原因在于被断开连接的那一方。因为当断开连接时,被动方接收到断开连接请求时,可能正在进行数据的传输,无法立即断开连接,导致只能先发出一次确认报文,告诉主动方我接受到了你的断开连接请求,但是我正在传输数据,无法立即断开。等待被动方完成数据传输之后,再发送一次确认断开连接的报文。因为确认断开的操作需要两次报文的传输才能完成,所以导致挥手多一次
。
三次握手能否改为两次握手?
不能。TCP通信需要建立可靠的连接,并且保证数据的有效性。要确保通信双方都具有数据收发能力,如果取消第三握手,那么**服务器无从知晓不知道客户端是否具有数据接收能力
。另外,在TCP发送数据时,不会将数据全部发送完,而是分次发送。在建立TCP连接时另外重要的一点就是双方确认数据发送的初始序列。后面数据序列都是基于初始序列而来,如果取消第三次握手,服务器也会不知道客户端是否完成初始序列的确认
**。
为什么主动断开方在发送第四次Ack报文后要进入time_wait?
因为第四次的Ack包可能会丢失
,此时主动方立即关闭连接,导致**被动方无法接收到最后的Ack报文
,而主动方已经关闭无从知晓,而导致被动方一直处于last_ack阶段
**。如果被动方在一定时间内没有接受到第四次的Ack报文,则会再次发送Fin包+Ack包,而主动方在time_wait阶段再次接收Fin包+Ack包,会回应Ack包,等待被动方在time_wait时间内没有发送其他报文,说明被动方已经正常关闭,最后主动方完成关闭。
TCP连接连接过程中客户端出现问题会怎么样?
TCP连接中可以**在服务器端设置保活参数
,服务器端每次成功接受到数据都会刷新保活时间
。如果客户端发生问题,在保活时间内没有发送数据给服务器端
,那么服务器端会发送探测报文
。如果没有接收到客户端对探测报文的响应
,那么服务器端最终认为客户端出现问题,断开TCP连接
**,避免占用服务器资源。
浏览器事件循环机制
浏览器
前置知识
:我们要知道js是一门单线程的语言,同一时刻只能执行一个任务,那么如果一个任务耗时太久(3S的定时器,返回数据量庞大的后端接口)岂不是会导致代码的执行卡住?(必须等待当前任务完成,才能继续执行后面的代码)。浏览器为了解决这个问题,设计了其他线程来模拟js实现多线程的效果。
渲染进程中的线程
:浏览器中每一个tab都具有一个单独的渲染进程,这也是为什么一个tab页崩溃不会影响到其他tab的原因。在**每一个渲染进程中又会存在许多线程,它们分别承担不同的任务
**。
js引擎线程是专门处理js代码的,我们所说的单线程就是针对于它。http请求线程则是专门处理http请求的…当js解析到一段执行http请求代码或者定时器代码,不会执行这些代码而是将这些代码放入对应的线程(异步操作)。避免这些耗时操作影响后面的代码(同步代码)执行。
任务队列
:当异步操作完成耗时操作的处理后(定时器到,请求数据返回),js引擎何时会去执行异步任务剩下的代码呢?当任务异步操作完成后,任务会进入一个任务队列,等待js引擎在当前**事件循环周期内把同步代码执行完毕
后,会去任务队列中去取任务放入执行栈中完成剩下代码的执行
**。
微队列与宏队列
:在任务队列中,又可以分为微队列和宏队列。微队列中的任务会先被js引擎线程取出来执行,宏队列中的任务只有当微队列空的时候才会被取出执行。整体的执行顺序是**执行栈任务>微队列任务>宏任务队列
。setTime(),setInterval()
的回调会进入宏队列
。promise的then()、catch()回调,new MutationObserver(),async/await的await
会进入微队列
**。
从以上可知,浏览器通过提供多种线程,以及线程之间的配合完成了对js的多线程模拟,但本质上js还是单线程的,可能都会产生一些问题。
定时器误差
:定时器属于宏任务,定时结束后回进入宏队列。而宏队列会等待执行栈中同步代码和微队列中任务执行完毕后才会执行,这样可能导致定时器已经结束了,但是回调无法立即执行产生定时器误差。
队列**。**
promise的then()、catch()回调,new MutationObserver(),async/await的await**会进入**
微队列``**。
从以上可知,浏览器通过提供多种线程,以及线程之间的配合完成了对js的多线程模拟,但本质上js还是单线程的,可能都会产生一些问题。
定时器误差
:定时器属于宏任务,定时结束后回进入宏队列。而宏队列会等待执行栈中同步代码和微队列中任务执行完毕后才会执行,这样可能导致定时器已经结束了,但是回调无法立即执行产生定时器误差。
备注:如果图片侵权,请及时与本人联系,会第一时间处理。
标签:web,01,http,请求,服务器端,TCP,基本常识,服务器,客户端 From: https://blog.csdn.net/weixin_62652659/article/details/143814089