快速搭建
安装express
创建一个文件夹,作为后端服务目录,然后通过命令行界面进入到该目录下,执行以下命令。
npm i express
创建并启动web服务
- 创建app.js文件
- 将以下代码复制到app.js文件中
//第一步:引入express const express=require('express) //第二步:调用express函数,生成web服务对象赋值为app const app=express() //监听服务的80端口 app.listen(80,()=>{ console.log('服务已启动') })
- 执行
node app.js
命令,然后就在本机的80端口启动了后端服务。
书写GET和POST请求
//第一步:引入express
const express=require('express)
//第二步:调用express函数,生成web服务对象赋值为app
const app=express()
=================GET请求无参数=================
app.get('/home',(req,res)=>{
//默认有两个req是请求,res是响应,我们需要返回给客户端的东西通过res.send返回
res.send('请求了home接口')
})
=================GET请求params参数=================
//例如:http://127.0.0.1/home/张三/18
app.get('/home/:id/:age',(req,res)=>{
//上面的这种形式传参是params形式,通过req.params即可获取传来的参数.
//这里的参数名称可以与前端的不一致,这里可以自己随便定义,
console.log(req.params)
//打印结果{id:'张三',age:'18'}
})
=================GET请求query参数=================
//例如:http://127.0.0.1/home?name=张三&age=18
app.get('/home',(req,res)=>{
//上面的这种形式传参是params形式,通过req.query即可获取传来的参数.
console.log(req.params)
//打印结果{name:'张三',age:'18'}
})
//第三步:监听服务的80端口
app.listen(80,()=>{
console.log('服务已启动')
})
express静态资源文件
这里就是为了将静态的资源暴露出去给别人访问,比如图片、log这些东西
核心代码: app.use(express.static(‘<静态资源目录>’))
const express=require('express)
const app=express()
======================基本使用====================
//假设在public目录下放了一张logo.png图片。当我们想要访问这张图片的时候则需要加下面这行代码,否则无法访问到图片,
//作用:将public目录下的资源对外暴露,且可以访问,但访问路径不包括public
//例如:http://127.0.0.1/logo.png 即可访问
app.use(express.static('public'))
======================进阶使用====================
//如果我又暴露了一个静态资源文件,且该静态资源文件下也有logo.png。则根据app.use的顺序执行,谁在前面展示谁的图片。
app.use(express.static('static'))
======================综合使用====================
//如果我想根据不同的静态资源展示不同的图片怎么办?直接加前缀即可,这里如果不加前缀则安装书写顺序展示。
app.use('/public',express.static('public')) //http://127.0.0.1/public/logo.png 即可访问
app.use('/static',express.static('public')) //http://127.0.0.1/static/logo.png 即可访问
app.listen(80,()=>{
console.log('服务已启动')
})
路由
const express=require('express')
const router=express.Router()
router.get('/',()=>{})
module.exports.router=router
module是一个模块的全局对象,每个js文件就是一个模块,当我们通过require引入一个模块的时候,其实引入的是该模块的全局变量modules下的exports对象,所以我们向外暴露只要暴露module下的exports对象即可,就是往exports里面加key:value即可。 module.exports和exports等价,如果同时暴露则module.exports优先级高
快捷启动nodemon
不需要每次修改完app.js之后手动重启了,直接通过安装nodemon,让nodemon帮你自动重启即可
npm i -g nodemon
安装完成之后,以后启动项目不需要用 node 项目名.js
,用nodemon 项目名.js
启动,后面修改代码就不需要手动重启了。
中间件
全局中间件
//判断当前是函数还是中间件,看有没有这个next参数
const mw=(req,res,next)=>{
console.log('mw')
// 这里一定要写next,否则会在这里卡住
next()
}
//全局注册中间件,当无论哪个请求过来的时候,先调用这个中间件,在调用请求的函数
app.use(mw)
app.get('/',(req,res)=>{
res.send('get请求')
})
结果:
mw
get请求
注意
中间件的req和res 和 路由处理函数的req和res是共享的,所以我们可以在处理中间件的时候挂在一些属性,这样在路由处理函数的时候就可以调用了
局部中间件
const mw=(req,res,next)=>{
console.log('mw')
// 这里一定要写next,否则会在这里卡住
next()
}
//再中间加入中间件函数,只有当请求地址为/的时候才出发这个中间件函数,在其他请求的时候则不会触发
app.get('/',mw,(req,res)=>{
res.send('get请求')
})
//如果需要执行多个中间件,则可以用数组也可以用多个逗号隔开。
app.get('/',[mw,mw1,mw2,....],(req,res)=>{
res.send('get请求')
})
中间件注意事项
- 一定要在路由之前注册中间件
- 客户端发来的请求可以调用多个中间件进行处理
- 连续的中间件调用共享req和res
- 中间件代码完成之后一定要调用next()函数
- next()函数之后不要写任何的逻辑代码
中间件的分类
-
应用级别的中间件
绑定到app身上的中间件叫做应用级别的中间件。
例如:app.use((req,res,next)=>{})
中间件应该放在所有的路由之前,否则中间的逻辑代码将不会处理
-
路由级别的中间件
绑定到expres.Router()身上的叫做路由级别的中间件
例如:router.use((req,res,next)=>{}) -
错误级别的中间件
专门处理程序运行过程中出现错误的时候逻辑处理,防止程序崩溃
错误中间件一定要放在所有的路由之后,否则捕获不到
function(err,req,res,next){
}app.use((err,req,res,next)=>{ res.send(err.message) }) app.get('/',()=>{ throw new Error('服务器崩溃') })
-
express内置的中间件
- express.static(<目录名称>). 托管静态资源,可以在任意版本使用
- express.json(). 解析JSON数据,仅在4.16.0版本及以后的版本可以使用
- express.urlencoded() 解析表单数据,仅在4.16.0版本及以后的版本可以使用
============以下为固定代码========!!!放在路由之前!!!!
app.use(express.json())
app.use(express.urlencoded({extended:false}))
获取encoded和json数据,通过req.body获取,因为上面两个中间件会把解析好的数据自动挂在到body身上
- 第三方中间件
自定义中间件
监听req的data事件
app.use((req,res,next)=>{
//监听req的data事件,当客户端把数据发送给服务端的时候会触发data事件,我们只要监听到data事件触发就代表有数据传输,但是数据过大的时候客户端会采用分段传输,所以我们需要对传输数据做拼接
let str=''
req.on('data',(chunk)=>{
str+=chunk
})
})
监听req的end事件
app.use((req,res,next)=>{
//监听req的end事件,代表数据传输已经完成,加下来对数据处理并挂载到body身上即可
req.on('end',(chunk)=>{
console.log(str,'@@')
})
})
跨域问题解决cors
- 第一步安装
npm i cors
- 第二步引入
const cors=require('cors')
- 第三步注册
app.use(cors())
注意:需要在路由之前注册,否则不生效
cors的配置
1. 允许全部域名跨域访问: res.setHeader('Access-Control-Allow-Origin','*')
2. 允许get、post意外的请求方法,例如:delete、put等等:res.setHeader('Access-Control-Allow-Method','*')
3.允许携带额外的请求头,例如Content-type和X-Custom-type,添加多个请求头的时候需要用逗号分隔: res.setHeader('Access-Control-Allow-Header','Content-type,X-Custom-type')