2.1路由的概念
1.什么是路由
广义上来讲,路由就是映射关系
2.现实生活中的路由
3. Express中的路由
在Express中,路由指的是客户端的请求与服务器处理函数之间的映射关系。
Express中的路由分3部分组成,分别是请求的类型、请求的URL地址、外理函数,格式如下:
4. Express中的路由的例子
5.路由的匹配过程
每当一个请求到达服务器之后,需要先经过路由的匹配,只有匹配成功之后,才会调用对应的处理函数。
在匹配时,会按照路由的顺序进行匹配,如果请求类型和请求的URL同时匹配成功,则Express会将这次请求,转
交给对应的function函数进行处理。
路由匹配的注意点:
①按照定义的先后顺序进行匹配
②请求类型和请求的URL同时匹配成功,才会调用对应的处理函数
2.2 路由的使用
1.最简单的用法
在Express中使用路由最简单的方式,就是把路由挂载到app上,示例代码如下:
2.模块化路由
为了方便对路由进行模块化的管理, Express 不建议将路由直接挂载到app上,而是推荐将路由抽离为单独的模块。将路由抽离为单独模块的步骤如下:
①创建路由模块对应的js文件
②调用express.Router(函数创建路由对象
③向路由对象上挂载具体的路由
④使用module.exports向外共享路由对象
3.创建路由模块
4.注册路由模块
5.为路由模块添加前缀
类似于托管静态资源时,为静态资源统一挂载访问前缀一 样, 路由模块添加前缀的方式也非常简单:
3.1中间件的概念
1.什么是中间件
中间件(Middleware ) , 特指业务流程的中间处理环节。
2.现实生活中的例子
在处理污水的时候,- 般都要经过三个处理环节,从而保证处理过后的废水,达到排放标准。
处理污水的这三个中间处理环节,就可以叫做中间件。
3. Express中间件的调用流程
当一个请求到达Express的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。
4. Express中间件的格式
Express的中间件,本质上就是一-个function处理函数,Express 中间件的格式如下:
注意:中间件函数的形参列表中,必须包含next参数。而路由处理函数中只包含req和res.
5. next函数的作用
next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。
3.2 Express中间件的初体验
1.定义中间件函数
可以通过如下的方式,定义一个最简单的中间件函数:
2.全局生效的中间件
客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。
通过调用app.use(中间件函数),即可定义一个全局生效的中间件.示例代码如下:
3.定义全局中间件的简化形式
4.中间件的作用
多个中间件之间,共享同-份req和rese基于这样的特性,我们可以在上游的中间件中,统-为req或res对象添加自定义的属性或方法,供下游的中间件或路由进行使用。
5.定义多个全局中间件
可以使用app.use0连续定义多个全局中间件。客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行调用,示例代码如下:
6.局部生效的中间件
不使用app.use0定义的中间件,叫做局部生效的中间件,示例代码如下: .
7.定义多个局部中间件
8.了解中间件的5个使用注意事项:
①一定要在路由之前注册中间件
②客户端发送过来的请求,可以连续调用多个中间件进行处理
③国执行完中间件的业务代码之后,不要忘记调用next0函数
④为了防止代码逻辑混乱,调用next0函数后不要再写额外的代码
⑤连续调用多个中间件时,多个中间件之间,共享req和res对象
3.3中间件的分类
为了方便大家理解和记忆中间件的使用,Express 官方把常见的中间件用法,分成了5大类,分别是:
①应用级别的中间件
②路由级别的中间件
③错误级别的中间件
④Express 内置的中间件
⑤第三方的中间件
1.应用级别的中间件
通过app.use0或app.get0或app.postO,绑定到app实例上的中间件,叫做应用级别的中间件,代码示例如下:
2.路由级别的中间件
绑定到express. Router(实例上的中间件,叫做路由级别的中间件。它的用法和应用级别中间件没有任何区别。只不过,应用级别中间件是绑定到app实例上,路由级别中间件绑定到router实例上,代码示例如下:
3.错误级别的中间件
错误级别中间件的作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。
格式:错误级别中间件的function处理函数中,必须有4个形参,形参顺序从前到后,分别是(err, req, res、next)。
注意:错误级别的中间件,必须注册在所有路由之后! .
4. Express内置的中间件
自Express 4.16.0版本开始,Express 内置了3个常用的中间件,极大的提高了Express 项目的开发效率和体验:
①express.static 快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS样式等(无兼容性)
②expressjson 解析JSON格式的请求体数据(有兼容性,仅在4.16.0+版本中可用)
③express.urlencoded 解析URL-encoded格式的请求体数据(有兼容性,仅在4.16.0+版本中可用)
5.第三方的中间件
非Express言方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,大家可以按需下载井配置
第三方中间件,从而提高项目的开发效率。
例如:在express@4.16.0之前的版本中,经常使用body-parser这个第三方中间件,来解析请求体数据。使用步骤如下:
①运行npm install body- parser安装中间件
②使用require导入中间件
③调用app.use0注册并使用中间件
3.4自定义中间件
1.需求描述与实现步骤
自己手动模拟-个类似于express.urlencoded这样的中间件,来解析POST提交到服务器的表单数据。
实现步骤:
①定义中间件
②监听req的data事件
③监听req的end事件
④使用querystring模块解析请求体数据
⑤将解析出来的数据对象挂载为reg.body
2.定义中间件
使用app.use0来定义全局生效的中间件,代码如下:
3.监听req的data事件
在中间件中,需要监听req对象的data事件,来获取客户端发送到服务器的数据。
如果数据量比较大,无法一次性发送完毕, 则客户端会把数据切割后.分批发送到服务器。所以data事件可能会触发多次,每一次触发data事件时,获取到数据只是完整数据的一部分,需要手动对接收到的数据进行拼接。
4.监听req的end事件
当请求体数据接收完毕之后,会自动触发req的end事件。
因此,我们可以在req的end事件中拿到并处理完整的请求体数据。示例代码如下:
5.使用querystring模块解析请求体数据
Nodejs内置了-个querystring 模块,专门用来处理查询字符串。通过这个模块提供的parse0函数.可以轻松把查询字符串,解析成对象的格式。示例代码如下:
6.将解析出来的数据对象挂载为req.body
上游的中间件和下游的中间件及路由之间,共享同-份req和res.因此,我们可以将解析出来的数据,挂载为req的自定义属性,命名为req.body,供下游使用。示例代码如下:
7.将自定义中间件封装为模块
为了优化代码的结构,我们可以把自定义的中间件函数,封装为独立的模块,示例代码如下:
4.1创建基本的服务器
4.2创建API路由模块
4.3编写GET接口
4.4编写POST接口
4.5 CORS跨域资源共享
1.接口的跨域问题
刚才编写的GET和POST接口,存在一个很严重的问题: 不支持跨域请求。
解决接口跨域问题的方案主要有两种: .
①CORS (主流的解决方案,推荐使用)
②JSONP (有缺陷的解决方案:只支持GET请求)
2.使用cors中间件解决跨域问题
cors是Express的一个第 三方中间件。通过安装和配置cors中间件,可以很方便地解决跨域问题。
使用步骤分为如下3步:
①运行npm install cors安装中间件
②使用const cors = require('cors")导入中间件
③在路由之前调用app.use(cors0)配置中间件
3.什么是CORS
CORS (Cross-Origin Resource Sharing,跨域资源共享)由一系列HTTP响应头组成,这些HTTP响应头决定浏览器是否阻止前端Js代码跨域获取资源.
浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了CORS相关的HTTP响应头,就可以解除浏览器端的跨域访问限制.
4. CORS的注意事项
①CORS主要在服务器端进行配置.客户端浏览器无须做任何额外的配置,即可请求开启了CORS的接口。
②CORS在浏览器中有兼容性。只有支持XMLHttpRequest Level2的浏览器,才能正常访问开启了CORS的服务端接口(例如: IE10+、 Chrome4+、FireFox3.5+).
5. CORS响应头部- Access-Control-Allow-Origin
响应头部中可以携带一个Access-Control-Allow-Origin字段,其语法如下:
其中,origin 参数的值指定了允许访问该资源的外城URL.
例如,下面的字段值将只允许来自http://itcast.cn 的请求: .
如果指定了Access-Control-Allow-Origin 字段的值为通配符*.表示允许来自任何域的请求,示例代码如下:
6. CORS响应头部- Access-Control-Allow-Headers
默认情况下,CORS仅支持客户端向服务器发送如下的9个请求头: .
Accept. Accept-Language. Content-Language. DPR、 Downlink. Save-Data. Viewport-Width. Width、
Content-Type (值仅限于 text/plain. multipart/form -data. application/x www- form urlencoded三者之一)如果客户端向服务器发送了额外的请求头信息。则需要在服务器端.通过Accss-Control-Allow-Headers对额外的请求头进行声明,否则这次请求会失败!
7. CORS响应头部- Access-Control-Allow-Methods
默认情况下,CORS仅支持客户端发起GET、POST. HEAD请求。
如果客户端希望通过PUT. DELETE 等方式请求服务器的资源。则需要在服务器端,通过Access-Control-Alow-Methods
来指明实际请求所允许使用的HTTP方法。
示例代码如下:
8. CORS请求的分类
客户端在请求CORS接口时,根据请求方式和请求头的不同,可以将CORS的请求分为两大类,分别是:
①简单请求
②预检请求
9.简单请求
同时满足以下两大条件的请求,就属于简单请求:
①请求方式: GET、POST、 HEAD三者之一
②HTTP 头部信息不超过以下几种字段:无自定义头部字段、Accept、 Accept Language、Content-Language. DPR、
Downlink. Save-Data. Viewport-Width. Width. Content-Type (只有三个值application/x-www-form-
urlencoded. multipart/form-data. text/plain)
10.预检请求
只要符合以下任何一个条件的请求,都需要进行预检请求:
①请求方式为 GET、POST、HEAD之外的请求Method类型
②请求头中包含自定义头部宇段
③向服务器发送了application/json 格式的数据
在浏览器与服务器正式通信之前,浏览器会先发送OPTION请求进行预检,以获知服务器是否允许该实际请求。所以这一次的OPTION请求称为“预检请求”.服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。
11.简单请求和预检请求的区别
简单请求的特点:客户端与服务器之间只会发生1次请求。
预检请求的特点:客户端与服务器之间会发生两次请求,OPTION 预检请求成功之后,才会发起真正的请求。
4.6 JSONP接口
1.回顾JSONP的概念与特点
概念:浏览器端通过<script>标签的src属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种的方式叫做JSONP。
特点:
①JSONP 不属于真正的Ajax请求,因为它没有使用XMLHttpRequest这个对象。
②JSONP 仅支持GET请求,不支持POST、PUT、DELETE 等请求。
2.创建JSONP接口的注意事项
如果项目中已经配置了CORS跨域资源共享,为了防止冲突,必须在配置CORS中间件之前声明JSONP的接口。否则JSONP接口会被处理成开启了CORS的接口。示例代码如下:
3.实现JSONP接口的步骤
①获取客户端发送过来的回调函数的名字
②得到要通过JSONP形式发送给客户端的数据
③根据前两步得到的数据,拼接出一个函数调用的字符串
④把上一步拼接得到的字符串,响应给客户端的<pcript>标签进行解析执行
4.实现JSONP接口的具体代码
5.在网页中使用jQuery发起JSONP请求
调用$.ajax0函数,提供JSONP的配置选项,从而发起JSONP请求,示例代码如下:
目标
◆能够知道如何配置MySQL数据库环境
◆能够认识并使用常见的SQL语句操作数据库
◆能够在Express中操作MySQL数据库
◆能够了解Session的实现原理
◆能够了解JWT的实现原理
1.数据库的基本概念
1.1什么是数据库
数据库(database) 是用来组织、存储和管理数据的仓库。
当今世界是一个充满着数据的互联网世界,充斥着大量的数据。数据的来源有很多,比如出行记录、消费记录.浏览的网页、发送的消息等等。除了文本类型的数据,图像、音乐、声音都是数据。
为了方便管理互联网世界中的数据,就有了数据库管理系统的概念(简称:数据库)。用户可以对数据库中的数据进行新增、查询、更新、删除等操作。
1.2 常见的致据库及分类
市面上的数据库有很多种.最常见的数据库有如下几个:
●MySQL 数据库(目前使用最广泛、流行度最高的开源免费数据库: Community + Enterprise)
●Oracle 数据库(收费)
●SQL Server数据库(收费)
●Mongodb 数据库(Community + Enterprise)
其中,MySQL. Orade、 SQL Server属于传统型数据库(又叫做:关系型数据库或SQL数据库) ,这三者的设计理念相同,用法比较类似。
而Mongodb属于新型数据库(又叫做:非关系型数据库或NoSQL数据库),它在一定程度上弥补了传统型数据库的缺陷
1.3传统型数据库的数据组织结构
1. Excel的数据组织结构
每个Excel中,数据的组织结构分别为工作薄、工作表、数据行、列这4大部分组成。
①整个Excel叫做工作薄
②users 和books是工作表
③users 工作表中有3行数据
④每行数据由6列信息组成
⑤每列信息都有对应的数据类型
2.传统型数据库的数据组织结构
在传统型数据库中,数据的组织结构分为数据库(database).数据表(table). 数据行(row)、 字段(field)这 4大部分组成。
①数据库类似于 Excel的工作薄
②数据表类似于 Excel的工作表
3.国数据行类似于 Excel 的每一行数据
④字段类似于Excel 的列
⑤每个字段都有对应的数据类型
3.实际开发中库、表、行、字段的关系
①在实际项目开发中,-般情况下,每个项目都对应独立的数据库。
②不同的数据,要存储到数据库的不同表中,例如:用户数据存储到users表中,图书数据存储到books表中。
③每个表中具体存储哪些信息,由字段来决定,例如:我们可以为users表设计id、username. password 这3个字段。
④表中的行,代表每一条具体的数据。
2.1了解需要安装哪些MySQL相关的软件
对于开发人员来说,只需要安装MySQL Server和MySQL Workbench这两个软件。就能满足开发的需要了。
●MySQL Server:专门用来提供数据存储和服务的软件。
●MySQL Workbench:可视化的MySQL管理工具,通过它,可以方便的操作存储在MySQL Server中的数据。
2.2 MySQL在Mac环境下的安装
在Mac环境下安装MySQL的过程比Windows环境下的步骤简单很多:
①先运行mysql-8.0.19-macos10.15-x86 64.dmg这个安装包,将MySQL Server 安装到Mac系统
②再运行mysql-workbench-community-8.0.19-macos-x86 64.dmg这个安装包,将可视化的MySQL
Workbench工具安装到Mac系统
2.3 MySQL在Windows环境下的安装
在Windows环境下安装MySQL,只需要运行mysql-installer-community-8.0.19.0.msi 这个安装包。就能一次性将MySQL Server和MySQL Workbench安装到自己的电脑上。
3.1使用MySQL Workbench管理数据库
1.连接数据库
2.了解主界面的组成部分
3.创建数据库
4.创建数据表
DataType数据类型:
①int 整数
②varchar(len) 字符串
③tinyint(1) 布尔值
字段的特殊标识:
①PK (Primary Key)主键、唯- -标识
②NN (Not Null)值不允许为空
③UQ (Unique)值唯--
4.AI (Auto Increment)值自动增长
5.向表中写入数据
3.2使用SQL管理数据库
1.什么是SQL
SQL (英文全称: Structured Query Language)是结构化查询语言,专门用来访问和处理数据库的编程语言。能够让我们以编程的形式,操作数据库里面的数据.
三个关键点:
①SQL 是-一门数据库编程语言
②使用SQL语言编写出来的代码,叫做SQL语句
③SQL语言只能在关系型数据库中使用(例如MySQL、Oracle. SQL Server)。非关系型数据库(例如Mongpdb)
不支持SQL语言
2. SQL能做什么
①从数据库中查询数据
②向数据库中插入新的数据
③更新数据库中的数据
④从数据库删除数据
⑤可以创建新数据库
⑥可在数据库中创建新表
⑦可在数据库中创建存储过程、 视图
⑧etC...
3. SQL的学习目标
重点掌握如何使用SQL从数据表中:
查询数据(select)、 插入数据(insert into)、 更新数据(update) 、 删除数据(delete)
额外需要掌握的4种SQL语法: .
where条件、and 和or运算符、order by排序、count(') 函数
额外需要掌握的4种SQL语法:
where条件、and 和or运算符、order by排序,count(*) 函数
1.语法
SELECT语句用于从表中查询数据。执行的结果被存储在一个结果表中 (称为结果集) . 语法格式如下:
2. SELECT *示例
我们希望从users表中选取所有的列,可以使用符号*取代列的名称,示例如下:
3. SELECT列名称示例
如需获取名为"username"和"password"的列的内容(从名为'users"的数据库表),请使用下面的SELECT语句:
1.语法
INSERT INTO语句用于向数据表中插入新的数据行,语法格式如下:
2. INSERT INTO示例
向users表中,插入-条username为tony stark, password 为098123的用户数据,示例如下:
Update语句用于修改表中的数据。语法格式如下:
2. UPDATE示例-更新某-行中的-个列
把users表中id为7的用户密码,更新为88888.示例如下:
3. UPDATE示例-更新某- -行中的若干列
把users表中id为2的用户密码和用户状态,分别更新为admin123和1.示例如下:
DELETE语句用于删除表中的行。语法格式如下:
2. DELETE示例
从users表中,删除id为4的用户,示例如下:
3.7 SQL的WHERE子句
1.语法
WHERE子句用于限定选择的标准。在SELECT. UPDATE、 DELETE 语句中,皆可使用WHERE子句来限定选择的标准。
2.可在WHERE子句中使用的运算符
下面的运算符可在WHERE子句中使用,用来限定选择的标准:
3. WHERE子句示例
可以通过WHERE子句来限定SELECT的查询条件: .
AND和OR可在WHERE子语句中把两个或多个条件结合起来。
AND表示必须同时满足多个条件.相当于JavaScript中的&&u运算符,例如if(a!== 10 &&a!== 20)
OR表示只要满足任意一个条件即可,相当于JavaScript 中的Il运算符,例如if(a!== 10||a!== 20)
2. AND运算符示例
使用AND来显示所有status 为0,并且id小于3的用户:
2. OR运算符示例
使用OR来显示所有status 为1,或者username为zs的用户:
3.9 SQL的ORDER BY子句
1.语法
ORDER BY语句用于根据指定的列对结果集进行排序。
ORDER BY语句默认按照升序对记录进行排序。
如果您希望按照降序对记录进行排序,可以使用DESC关键字。
2. ORDER BY子句-升序排序
对users表中的数据,按照status字段进行升序排序,示例如下:
3. ORDER BY子句-降序排序
对users表中的数据,按照id字段进行降序排序,示例如下:
desc表示降序排序 asc 表示升序排序(默认)
4. ORDER BY子句-多重排序
对users表中的数据,先按照status字段进行降序排序,再按照usermame的字母顺序,进行升序排序,示例如下:
3.10 SQL的COUNT(*)函数
1.语法
COUNT(*)函数用于返回查询结果的总数据条数,语法格式如下:
查询users表中status为0的总数据条数:
select count(*) from useres where status=0
2.使用AS为列设置别名
4.1在项目中操作数据库的步骤
①安装操作MySQL数据库的第三方模块(mysql)
②通过mysql模块连接到MySQL数据库
③通过mysql模块执行SQL语句.
4.2安装与配置mysqI模块
1.安装mysql模块
mysql模块是托管于npm上的第三方模块。它提供了在Node.js项目中连接和操作MySQL数据库的能力。需要先运行如下命令,将mysql安装为项目的依赖包:
2.配置mysql模块
在使用mysql模块操作MySQL数据库之前,必须先对mysql模块进行必要的配置,主要的配置步骤如下:
3.测试mysql模块能否正常工作
调用db.query0函数,指定雯执行的SQL语句,通过回调函数拿到执行的结果:
1.查询数据
查询users表中所有的数据:
//查询users 表中所有的数据
const sqlStr =' select * from users '
db. query(sqlStr, (err, results) => {
//查询数据失败
if(err) return console. log(err . message)
//查询数据成功
console. log(results)
})
2.插入数据
向users表中新增数据,其中username为Spider-Man,password 为pec321.示例代码如下: .
// 1.要插入到users表中的数据对象
const user = { username: ' Spider-Man',password:' pcc321' }
// 2.待执行的SQL语句,其中英文的?表示占位符
const sqlStr = ' INSERT INTO users (username, password) VALUES (?, ?)'
// 3.使用数组的形式,依次为?占位符指定具体的值
db. query( sqlStr, [user .username, user . password], (err, results) => {
if (err) return console. log(err .message) //失败
if(results.affectedRows === 1) { console.log( '插入数据成功') } //成功
})
3.插入数据的便捷方式
向表中新增数据时,如果数据对象的每个属性和数据表的字段一- 对应,则可以通过如下方式快速插入数据: .
// 1.要插入到users 表中的数据对象
const user = { username: ' Spider -Man2' , password: ' pcc4321' }
// 2.待执行的SQL语句,其中英文的?表示占位符
const sqlStr = ' INSERT INTO users SET ?'
// 3.直接将数据对象当作占位符的值
db . query(sqlStr, user, (err, results) => {
if (err) return console. log(err . message) //失败
if(results . affectedRows === 1) { console. log( '插入数据成功') } // 成功
})
4.3使用mysq|模块操作MySQL数据库
4.更新数据
可以通过如下方式,更新表中的数据:
// 1.要更新的数据对象
const user = { id: 7, username: ' aaa', password: ' 000' }
// 2.要执行的SQL语句
const sqlStr = ' UPDATE users SET username=? , password=? WHERE id=? '
// 3.调用db.query() 执行SQL 语句的同时,使用数组依次为占位符指定具体的值
db . query(sqlStr, [user .username, user . password, user .id], (err, results) => {
if (err) return console. log(err .message) //失败
if (results . affectedRows === 1) { console. log( '更新数据成功! ') } /成功
})
5.更新数据的便捷方式
更新表数据时,如果数据对象的每个属性和数据表的字段一一对应,则可以通过如下方式快速更新表数据:
// 1.要更新的数据对象
const user = { id: 7, username: ' aaa', password: ' 000' }
// 2.要执行的SQL语句
const sqlStr = ' UPDATE users SET username=? , password=? WHERE id=? '
// 3.调用db.query() 执行SQL 语句的同时,使用数组依次为占位符指定具体的值
db . query(sqlStr, [user .username, user . password, user .id], (err, results) => {
if (err) return console. log(err .message) //失败
if (results . affectedRows === 1) { console. log( '更新数据成功! ') } /成功
})
6.删除数据
在删除数据时,推荐根据id 这样的唯一标识, 来删除对应的数据。示例如下:
//1.要执行的SQL语句
const sqlStr = 'DELETE FROM users WHERE id=? '
// 2.调用db.query() 执行SQL语句的同时,为占位符指定具体的值
//注意:如果SQL语句中有多个占位符,则必须使用数组为每个占位符指定具体的值
5 //如果SQL语句中只有一个占位符,则可以省略数组
db. query(sqlStr, 7, (err,results)=>{
if (err ) return console . log(err . message) //失败
if (results. affectedRows === 1) { console. log( '删除数据成功! ') } //成功
})
7.标记删除
使用DELETE语句,会把真正的把数据从表中删除掉。为了保险起见,推荐使用标记删除的形式,来模拟删除的动作。
所谓的标记删除,就是在表中设置类似于status 这样的状态字段,来标记当前这条数据是否被删除。
//标记删除:使用UPDATE语句替代DELETE语句;只更新数据的状态,并没有真正删除
db.query(' UPDATE USERS SET status=1 WHERE id=?', 6,(err, results) => {
if (err) return console. log(err .message) /失败
if (results. affectedRows === 1) { console. log( '删除数据成功! ') } //成功
})
5.1 Web开发模式
目前主流的Web开发模式有两种,分别是:
①基于服务端渲染的传统Web开发模式
②基于前后端分离的新型Web开发模式
1.服务端渲染的Web开发模式
服务端消染的概念:服务器发送给客户端的HTML页面,是在服务器通过字符串的拼接,动态生成的。因此,客户端不
需要使用Ajax这样的技术额外请求页面的数据。代码示例如下:
app . get( '/index.html', (req, res) => {
// 1.要渲染的数据
const user = { name: zS', age: 20 }
// 2.服务器端通过字符串的拼接,动态生成HTML内容
const html =‘<h1>姓名: ${user . name},年龄: ${user . age}</h1>
// 3.把生成好的页面内容响应给客户端。因此,客户端拿到的是带有真实数据的HTML 页面
res . send(html)
})
2.服务端渲染的优缺点
优点:
①前端耗时少。 因为服务器端负责动态生成HTML内容,浏览器只需要直接追染页面即可。尤其是移动端,更省电。
②有利于SEO,因为服务器端响应的是完整的HTML页面内容,所以爬虫更容易爬取获得信息,更有利于SEO。
缺点:
①占用服务器端资源。即服务器端完成HTML页面内容的拼接,如果请求较多。会对服务器造成一定的访问压力。
②不利于前后端分离,开发效率低。使用服务器端渣染,则无法进行分工合作,尤其对于前端复杂度高的项目,不利于项目高效开发。
3.前后端分离的Web开发模式
前后端分离的概念:前后端分离的开发模式,依赖于Ajax技术的广泛应用。简而言之,前后端分离的Web开发模式,就是后端只负责提供API接口,前端使用Ajax调用接口的开发模式。
4.前后端分离的优缺点
优点:
①开发体验好。 前端专注于UI页面的开发,后端专注于api的开发,且前端有更多的选择性。
②用户体验好。 Ajax 技术的广泛应用,极大的提高了用户的体验,可以轻松实现页面的局部刷新。
③减轻了服务器端的渲染压力。 因为页面最终是在每个用户的浏览器中生成的。
缺点:
①不利于 SEO,因为完整的HTML页面需要在客户端动态拼接完成,所以爬虫对无法爬取页面的有效信息。(解决方案:利用Vue React 等前端框架的SsR (server side render)技术能够很好的解决SEO问題! )
5.如何选择Web开发模式
不谈业务场景而言目选择使用何种开发模式都是要流氓。
●比如企业级网站,主要功能是展示而没有复杂的交互,井且需要良好的SEO,则这时我们就需要使用服务器端渲染:
●而类似后台管理项目,交互性比较强,不需要考虑SEO, 那么就可以使用前后端分离的开发模式。
另外,具体使用何种开发模式并不是绝对的,为了同时兼顾了首页的渲染速度和前后端分离的开发效率,一些网站采用了
首屏服务器端渣染+其他页面前后端分高的开发模式。
5.2身份认证
1.什么是身份认证
身份认证(Authentication) 又称“身份验证”、“鉴权” ,是指通过一-定的手段, 完成对用户身份的确认。
●日常生活中的身份认证随处可见,例如:高铁的验票乘车,手机的密码或指纹解锁,支付宝或微信的支付密码等。
●在Web开发中,也涉及到用户身份的认证,例如:各大网站的手机险证码登录、邮箱密码登录、二维码登录等。
2.为什么需要身份认证
身份认证的目的,是为了确认当前所声称为某种身份的用户,确实是所声称的用户。例如,你去找快递员取快递,你要怎么证明这份快递是你的。在互联网项目开发中,如何对用户的身份进行认证,是一个值得深入探讨的问题。
例如,如何才能保证网站不会错误的将“马云的存款数颠”显示到“马化腾的账户”上。
3.不同开发模式下的身份认证
对于服务端消染和前后端分离这两种开发模式来说,分别有着不同的身份认证方案:
①服务端洁染推荐使用 Session认证机制
②前后端分离推荐使用 JWT认证机制