Express
Express的基本使用:
1、安装:在项目所处的目录终端中执行代码:npm i express@4.17.1
2、创建基本的Web服务器
//1.导入express
const express=require('express')
//2.创建web服务器
const app=express()
//3.调用app.listen(端口号,启动成功后的回调函数),启动服务器
app.listen(80,()=>{
console.log('Express server running at http://127.0.0.1')
})
3、监听GET请求:
通过app.get()方法,可以监听客户端的GET请求,具体的语法格式如下:
//参数1:客户端请求的URL地址
//参数2:请求对应的处理函数
// req:请求对象
// res:响应对象
app.get('请求的URL地址',function(req,res){
//处理函数
})
4、监听POST请求:
通过app.post()方法,可以监听客户端的POST请求,具体的语法格式如下:
//参数1:客户端请求的URL地址
//参数2:请求对应的处理函数
// req:请求对象
// res:响应对象
app.post('请求的URL地址',function(req,res){
//处理函数
})
5、把内容响应给客户端
通过res.send()方法,可以把处理好的内容,发送给客户端
app.get('/user',function(req,res){
//向客户端发送JSON对象
res.send({name:'zhangsan',age:20,gender:'男'})
})
app.post('/user',function(req,res){
//想客户端发送文本内容
res.send('发送请求')
})
6、获取URL中携带的查询参数
通过req.query对象,可以访问到客户端通过查询字符串的形式,发送到服务器的参数
app.get( '/', function ( req, res ) {
// 通过req.query可以获取到客户端发送过来的查询参数
// 注意:默认情况下,req.query是一个空对象
console.log( req.query );
res.send( req.query )
} )
7、获取URL中的动态参数
通过req.params对象,可以访问到URL中,通过:匹配到的动态参数
//URL 地址中,可以通过:参数名 的形式,匹配动态参数值
app.get('/user/:id',(req,res)=>{
//req.params 默认是个空对象
//里面存放着通过 : 动态匹配到的参数值
console.log(req.params)
})
托管静态资源
1.express.static():可以非常方便的创建一个静态资源服务器,
代码如下:
app.use(express.static('public目录')) 可以访问public目录下得所有文件
访问clock中的文件可以直接在IP地址后加文件名,
例如:http://127.0.0.1/index.html
2.托管多个静态资源目录:多次调用express.static()方法即可,
访问静态资源文件时,该函数会根据目录的添加顺序查找所需要的文件
3.挂在路径前缀:app.use(‘/public’,express.static(‘public’))
此时可以通过带有/public 前缀的地址来访问public目录中的文件了
eg: 访问clock中的文件可以直接在IP地址后加文件名,
例如:http://127.0.0.1/public/index.html
http://127.0.0.1/public/index.css等等
nodemon
为什么要使用nodemon?
nodemon工具能够监听项目文件的变动,当代码被修改后,nodemon会自动帮助重启项目,极大地方便了开发和调试。
安装nodemon:npm i -g nodemon
使用nodemon:
原来:node index.js
将上面的终端命令替换为下面的命令,即可实现项目自动重启的效果
现在:nodemon index.js 报错则在前面加上npx ==> npx nodemon index.js
============================================================================
Express路由
什么是路由? 在Express中,路由指的是客户端的请求与服务器处理函数之间的映射关系
Express中的路由分为3部分:请求的类型、请求的URL地址和处理函数,格式如下:
app.METHOD(PATH,HANDLER)
METHOD 为请求类型
PATH 为请求的URL地址
HANDLER 为处理函数
举例:
// 匹配GET请求,且请求URL为 /
app.get(‘/’,function(req,res){
res.send(‘Hello World!And Express!’)
})
//匹配POST请求,且请求URL为 /
app.post(‘/’,function(req,res){
res.send(‘Got a Post request!’)
})
路由匹配过程:
当一个请求到达服务器后,首先进行路由的匹配(按照路由的顺序进行匹配查找),当 请求类型 和 请求URL地址 同时匹配成功,Express才会将此次请求交给对应的函数进行处理。
路由的使用:
// 挂载路由
app.get( '/', ( req, res ) => {
res.send( '获取请求成功!' )
// res.send() 发送各种类型的响应。使用res.send()方法,服务器才会响应给客户端数据。
} )
app.post( '/', ( req, res ) => {
res.send( '发送请求成功!Post Request ' )
} )
路由 模块化:为方便对路由进行模块化的管理,可以将路由抽离为单独模块
步骤:
1.创建路由模块对应的js文件
2.调用express.Router()函数创建路由对象
3.向路由对象上面挂载具体的路由
4.使用module.exports向外共享路由对象
// 导入express模块
const express = require( 'express' )
// 创建路由对象
const router = express.Router()
// 向路由对象上面挂载具体的路由
router.get( '/user/list', ( req, res ) => {
res.send( '您得到回复,Get user list' )
} )
router.post( '/user/add', ( req, res ) => {
res.send( '您发送了一个请求!Add new user!' )
} )
// 使用module.exports向外共享路由对象
module.exports = router
5.使用app.use()函数注册路由模块
// 导入路由模块
const router = require( './03.Router路由模块' )
// 注册路由模块
app.use(router)
给路由模块访问路径添加前缀:
类似于托管静态资源时,为静态资源统一挂载访问前缀一样,为路由模块添加前缀
//导入路由模块.js文件
const router = require( './03.Router' )
//使用app.use()注册路由模块,并添加统一的访问前缀 /app
app.use( '/app', router )
此时访问路径为:http://127.0.0.1/app/user/list
============================================================================
Express 中间件:特指 业务流程 的中间处理环节
Express中间件的 调用流程:
当一个请求到达Express的服务器之后,可以连续调用多个中间件,从而对这次请求进行 预处理
Express中间件的 格式:
app.get('/',function(req,res,next){
next();
})
//注意:中间件函数的形参列表中,必须包含next函数。而路由处理函数中只包含req和res
next函数的作用:
next函数时实现多个中间件连续调用的关键,他表示把流转关系 转交 给下一个中间件或路由
全局生效的中间件:
客户端发起的任何请求,在到达服务器后,都会触发的中间件,叫做全局生效的中间件。
通过调用app.use(中间件函数)定义一个全局生效的中间件。
```
//常量mw所指向的就是一个中间件函数
const mw=function(req,res,next){
console.log('这是一个最简单的中间件函数')
next()
}
//全局生效的中间件,使用app.use()方法使中间件生效
app.use(mw)
```
简化全局生效的中间件写法:
```
app.use(function(req,res,next){
console.log('这是一个简化的最简单的中间件函数')
next()
})
```
中间件的 作用:
在多个中间件之间,共享 同一份 req和res。所以可以在上游的中间件中,统一为req和res对象添加自定义的属性或方法,以供下游的中间件或路由进行使用。
定义多个全局中间件:
会按照中间件定义的顺序逐个进行调用
局部生效的中间件
不使用 app.use()定义的中间件,叫做局部生效的中间件:
```代码块
//定义中间件函数mw1
const mw1=function(req,res,next){
console.log('这是中间件函数')
next()
}
//mw1这个中间件只在 “当前路由中生效”,这种用法属于 局部生效的中间件
app.get('/',mw1,function(req,res){
res.send('Home page') //当前定义的函数是一个路由,因为没有next属性
})
//mw1 这个中间件不会影响下面改路由:因为,下面的路由访问的是 /user路径
app.get('/user',function(req,res){
res.send('User page。')
})
```
定义多个局部变量的中间件
可以在路由中使用以下两种方式调用局部中间件,局部中间件的个数可以任意多个
方法1:
app.get('/',mw1,mw2,function(req,res)=>{
res.send("Home Page1")
})
方法2:
app.get('/',[mw1,mw2],function(req,res)=>{
res.send("Home Page1")
})
中间件的注意事项:
1、中间件要放在路由之前注册
2、路由可以调用任意多个中间件
3、执行完中间件的业务代码后,不要忘记 调用 next()函数!!!!
4、为防止代码逻辑混乱,在next()函数之后不写额外代码
5、连续调用的多个中间件时,中间件共享req和res对象属性
Express 官方把常见的中间件用法,分成 5 大类:
1、应用级别的中间件:
通过 app.use() 或 app.get() 或 app.post() ,绑定到 app 实例上的中间件。
2、路由级别的中间件:
绑定到 express.Router() 实例上的中间件,叫做路由级别的中间件。路由级别中间件绑定到 router 实例上。
3、错误级别的中间件:
专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。
格式:错误级别中间件的 function 处理函数中,必须有 4 个形参,形参顺序从前到后,分别是 (err, req, res, next)
注意:错误级别的中间件,必须注册在所有路由之后!
4、Express 内置的中间件:Express 内置了 3 个常用的中间件
express.static 快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性)
express.json 解析 JSON 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)
express.urlencoded 解析 URL-encoded 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)
5、第三方的中间件:非 Express 官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,可以按需下载并配置第三方中间件,从而提高项目的开发效率。
使用步骤如下:
运行 npm install body-parser 安装中间件
使用 require 导入中间件
调用 app.use() 注册并使用中间件
注意:Express 内置的 express.urlencoded 中间件,就是基于 body-parser 这个第三方中间件进一步封装出来的。
自定义中间件
eg:自己手动模拟一个类似于 express.urlencoded 这样的中间件,来解析 POST 提交到服务器的表单数据。
实现步骤:
1、定义中间件
2、监听 req 的 data 事件
3、监听 req 的 end 事件
4、使用 querystring 模块解析请求体数据
5、将解析出来的数据对象挂载为 req.body
6、将自定义中间件封装为模块
代码块:
```
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
// 导入 Node.js 内置的 querystring 模块
const qs = require('querystring')
// 这是解析表单数据的中间件
app.use((req, res, next) => {
// 定义中间件具体的业务逻辑
// 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
let str = ''
// 2. 监听 req 的 data 事件
req.on('data', (chunk) => {
str += chunk
})
// 3. 监听 req 的 end 事件
req.on('end', () => {
// 在 str 中存放的是完整的请求体数据
// console.log(str)
// TODO: 把字符串格式的请求体数据,解析成对象格式
const body = qs.parse(str)
req.body = body
next()
})
})
app.post('/user', (req, res) => {
res.send(req.body)
})
// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
console.log('Express server running at http://127.0.0.1')
})
```
使用 Express 写接口:
1、创建基本的服务器
2、创建API路由模块
3、编写GET接口
4、编写POST接口
5、接口的跨域问题:
GET 和 POST接口,存在一个很严重的问题:不支持跨域请求。
1、解决接口跨域问题的方案主要有两种:
CORS(主流的解决方案,推荐使用)
JSONP(有缺陷的解决方案:只支持 GET 请求)
2、使用 cors 中间件解决跨域问题:
cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题。
使用步骤分为如下 3 步:
1、运行 npm install cors 安装中间件
2、使用 const cors = require('cors') 导入中间件
3、在路由之前调用 app.use(cors()) 配置中间件