1. 目前主流的 Web 开发模式有两种,分别是:
① 基于服务端渲染的传统Web 开发模式 前端耗时少, 有利于SEO , 占用服务器端资源, 开发效率低。
② 基于前后端分离的新型Web 开发模式 就是后端只负责提供API 接口,前端使用Ajax 调用接口的开发模式 , 用户体验好, 轻松实现页面的局部刷新, 减轻了服务器端的渲染压力 , 不利于 SEO , 因为完整的 HTML 页面需要在客户端动态拼接完成,所以爬虫对无法爬取页面的有效信息。(解决方 案:利用 Vue、React 等前端框架的SSR (server side render)技术能够很好的解决 SEO 问题!)
2. 不谈业务场景而盲目选择使用何种开发模式都是耍流氓。
-
比如企业级网站,主要功能是展示而没有复杂的交互,并且需要良好的SEO,则这时我们就需要使用服务器端渲染;
-
而类似后台管理页面,交互性比较强,不需要SEO 的考虑,那么就可以使用前后端分离的开发模式。
-
另外,具体使用何种开发模式并不是绝对的,为了同时兼顾了首页的渲染速度和前后端分离的开发效率,一些网站采用了 首屏服务器端渲染,即对于用户最开始打开的那个页面采用的是服务器端渲染,而其他的页面采用前后端分离开发模式。
3. 身份认证
为了确认当前所声称为某种身份的用户,确实是所声称的用户
3.1 不同开发模式下的身份认证
对于服务端渲染和前后端分离这两种开发模式来说,分别有着不同的身份认证方案:
① 服务端渲染推荐使用 Session 认证机制
② 前后端分离推荐使用JWT 认证机制
3.2 HTTP 协议的无状态性
指的是每次的HTTP 请求都是独立的,连续多个HTTP 请求之间没有直接的关系,服务器不会 主动保留每次HTTP 请求的状态。为了****突破 HTTP 无状态的限制,进而去使用身份认证
3.3 Cookie 在身份认证中的作用
客户端第一次请求服务器的时候,服务器通过响应头的形式,向客户端发送一个身份认证的Cookie,客户端会自动 将 Cookie 保存在浏览器中。随后,当客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的Cookie,通过请求头的形式发送给 服务器,服务器即可验明客户端的身份。
Cookie的几大特性:① 自动发送② 域名独立③ 过期时限④ 4KB 限制
Cookie 不具有安全性: 由于 Cookie 是存储在浏览器中的,而且浏览器也提供了读写Cookie 的 API,因此Cookie 很容易被伪造,不具有安全性。因此不建议服务器将重要的隐私数据,通过Cookie 的形式发送给浏览器**。**
为了提高身份认证的安全性, 引入认证机制
4. 了解 Session 认证的局限性
Session 认证机制需要配合 Cookie 才能实现。由于Cookie 默认不支持跨域访问,所以,当涉及前端跨域请求后端接口的时候,需要做很多额外的配置,才能实现跨域Session 认证。注意:
⚫ 当前端请求后端接口不存在跨域问题的时候,推荐使用Session 身份认证机制。
⚫ 当前端需要跨域请求后端接口的时候,不推荐使用Session 身份认证机制,推荐使用JWT 认证机制。
5. JWT是目前最流行的跨域认证解决方案。
通常由三部分组成,分别是 Header(头部)、Payload(有效荷载)、Signature(签名)。
Payload 部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。Header 和 Signature 是安全性相关的部分,只是为了保证Token 的安全性。
为了保证 JWT 字符串的安全性,防止JWT 字符串在网络传输过程中被别人破解,我们需要专门定义一个用于加密和解密 的 secret 密钥:① 当生成 JWT 字符串的时候,需要使用secret 密钥对用户的信息进行加密,最终得到加密好的 JWT 字符串② 当把 JWT 字符串解析还原成 JSON 对象的时候,需要使用secret 密钥进行解密
6. 中间件概念和中间件的分类
/**
* 1. 中间件的概念 Express 业务流程的中间处理环节
* 2. 中间件的流程
* 当一个请求到达express服务器之后, 可以连续调用多个中间件,
* 从而对这次请求进行预处理,上一个中间件的输出作为下一个的输入
* 处理完毕,响应这次请求(最终环节)
* 3. 中间件的格式
* 本质上是一个function处理函数
* 请求方式 - 路径 - 中间件函数
* app.get("/",(req,res,next)=>{
* next()
* })
* 注意: 中间件的形参列表中,必须包含 next参数,
* 而路由处理函数中只包含req 和 res
*
* 4. next()函数的作用
* next函数是实现多个中间件连续调用的关键, 它表示把流转关系转交给下一个中间件或路由
*
* 5**.中间件的注意事项**
* 一定要在路由之前注册中间件
* 执行完中间件的业务代码之后, 不要忘记调用 next() ,
* 多个中间件之间 ,共享req res 对象
* */
6.1 中间件分类
/**
* 应用级别的中间件 =>通过app.use(全局中间件) app.get(局部中间件) 绑定到<app实例>上的中间件
* 路由级别 => 绑定到express.Router()实例上的中间件 router.use()
* 错误级别 => 用来捕获整个项目发生的异常错误 ,防止程序奔溃 必须4 个参数 (err,req,res,next)
* app.use((err.req,res,next)=>{
* concole.log(err.message) // 一般的中间件注册在路由之前 ,
* res.send('Error:'+err.message) //而错误中间件必须注册在所有路由之后
* })
* Express 内置 =>
* 1. express.static 快速托管静态资源的内置中间件,无兼容性
* 2. express.json 解析JSON格式的请求体数据 (4.16+版本)
* app.use(express.josn())
* 3. express.urlencoded 解析URL-encoded格式的请求体数据(4.16+版本)
* app.use(express.urlencoded({extend:fasle}))
* 第三方的中间件 => body-parser第三方中间件,来解析请求体数据
* npm i body-parser 下载插件
*/
7. cors跨站资源共享
概念 cors由一系列http响应头组成 , 决定浏览器是否阻止前端跨域访问资源
浏览器的同源安全策略默认会阻止网页 跨域获取资源
1. 但如果接口服务器(服务端)配置了cors相关的 http响应头(Access-Control-Allow-Qrigin)
res.setHeader('Access-Control-Allow-Qrigin','*')
2. 默认情况下, cors 仅支持客户端向浏览器 发送9 个请求头,如果发送了额外的请求头信息,需要在服务器进行声明
允许客户端向服务器发送 X-Custom-Header请求头, 多个请求头之间使用英文的逗号隔开
res.setHeader('Access-Control-Allow-Headers','Content-Type,X-Custom-Header')
3. 默认情况下, cors仅支持GET , HEAD
res.setHeader('Access-Control-Allow-Methods','POST,DELETE')
res.setHeader('Access-Control-Allow-Methods','*') //允许所有
8. 请求分类
1.简单请求
* 同时满足以下两大条件的请求, 救属于简单请求,
* (1)请求方式 :GET POST HEAD s三者之一
* (2)HTTP头部消息不超过以下字段: 无自定义头部字段. Accept / Content-Type(只有三个值,application/x-www-form-utlEncodeed ,multipart/form-data , text/plain)
* 简单请求的特点:客户端与服务器之间只会发生一次请求。
2.预检请求
* 只要符合以下任何一个条件的请求, 都需要进行预检:
* (1) 请求方式为 GET POST HEAD 之外的请求Method
* (2) 请求头中包含自定义头部字段
* (3) 向服务器发送了application/josn格式的数据
* 正式通信之前, 浏览器会先发送OPTION请求的预检, 以获知服务器是否允许该实际请求, 服务器成功响应预检请求后, 才会发送真正的请求,并且携带真实数据
* 预检请求的特点:OPTION 预检请求成功之后,才会发起真正的请求。