一、express
express是一个基于nodejs开发的一个web框架,我们都知道,nodejs是一个用js语言开发服务端代码的框架,但是如果要用nodejs直接开发,那如何去处理请求的异常,如何管理进入各个页面的路由,如何处理众多的API请求等等,这都是一系列的问题,都需要自己去实现,而express框架就是帮你处理这些事情的,相当于把这些处理的代码都封装了,只管用就行了,express和nodejs的关系就像是JQ和js一样,原始的js去操作dom太麻烦了,直接用JQ简单多了。
安装:npm install express --save
引入express,启动服务,定义了一个get和一个post请求,可以去postman测试下
const express = require('express')
// 一个express的实例
const app = express()
// app.use((req, res) => {
// res.json({
// name: "李四"
// })
// })
app.get('/name/:age22', (req, res) => {
let {age22} = req.params
res.json({
result: 'tom',
age22
})
// res.send('我20了')
})
app.post('/age', (req, res) => {
res.send('我叫tom')
})
app.listen(3000, () => {
console.log('server启动成功。。')
})
// 纯nodejs写法
// const http = require('http')
// const server = http.createServer((req, res) => {
// })
二、路由、中间件
路由:所有的接口请求、静态文件请求的路径
文件目录结构:
路由使用的两种方式:
1.全局使用,如上图,在入口文件index.js文件中直接用app.get/post定义,如上图。
2.模块路由:在实际项目中肯定是要分模块的,不可能所有的路由都写在入口文件中,这样太不好维护了,所以就定义分模块的路由,使用方式如下:
先定义好分路由模块,写好接口,并且暴露出去,然后在入口文件index.js中注册即可
index.js(APP级别文件)
const express = require('express')
const userrouter = require('./router/demo')
const app = express()
// 路由
// router:get/post/put/delet...
app.get('/test', (req,res) => {
res.json({
mesg: 'test'
})
})
app.get('/test', (req,res) => {
res.json({
mesg: 'test'
})
})
app.all('/demo', (req,res) => {
res.json({
mesg: 'demo',
method: req.method
})
})
// 中间件:处理整个流程拦截中间某一个过程的函数
function demo_middleware(err, req,res,next) {
// 处理异常
// 处理业务功能,转交控制权,next
// 响应请求,->结束请求->当做路由的处理函数
// 使用场景:
// APP级别的:顶级地方注册(如该文件,项目的启动文件)
// router级别的:子路由中定义的
// 异常处理
}
// 要发送请求才会执行
function test(req,res,next) {
console.log('请求来了')
next()
}
app.use(test)
// 子路由:调用的子路由地址,使用路由,可加入父级路径,命名空间,如下的/user,如果该处调用的路由路径和APP级别路由路径一样,则会只调用APP级别路由
app.use('/user',userrouter)
app.use(express.static('static', {
// 不带后缀的请求默认设置一些后缀
extensions:['html', 'htm']
}))
// 定义中间件,在所有路由中使用
function middle(req,res,next) {
let {name} = req.query
if (!name || !name.length) {
res.json({
mesg:'缺少参数'
})
}else {
next()
}
}
app.all('*',middle)
app.listen(3000, () => {
console.log('服务启动')
})
中间件:对程序的某一过程进行拦截处理,处理完后移交下一步处理,如:vue中的前置路由守卫和后置路由守卫router.beforeEach,router.afterEach,如在路由接口请求中,对请求的参数需要校验, 校验完才能进行下一步处理
demo.js文件:
const express = require('express')
const router = express.Router() // 路由对象
router.use(function(req,res,next){
console.log('log路由来了')
next()
})
// 中间件:校验登入,若输入用户名和密码,返回该参数,否则返回“校验失败”
function valid_user(req,res,next) {
let {name, psd} = req.query
if (!name || !psd) {
res.json({
mesg: '校验失败'
})
}else{
req.formdata = {
name,
psd
}
next()
}
}
// 路由中链式中间件调用,数组中逗号接无数个中间件
router.get('/login', [valid_user], (req,res) => {
let {formdata} = req
res.json({
formdata,
mesg: '从demojs来的路由'
})
})
module.exports = router
异常处理:
// 异常处理,中间件的方式实现
// 定义一个异常(mesg未定义)
app.get('/err',(req,res) => {
throw new Error('服务器异常')
res.json({
mesg
})
})
function error_handle(err,req,res,next) {
if (err) {
res.status(500).json({
mesg: '服务器异常'
})
}
}
// 异常处理的注册放在程序的收口处,也就是所有路由的最后,404在express中并不是一个异常,
// 所以没有err对象,用中间件单独处理,当前面路由都没法匹配时,由404中间去处理
app.use(error_handle)
// 404异常处理
function not_found(req,res,next) {
res.json({
mesg: 'api不存在'
})
}
app.use(not_found)
三、报错解决办法
报错:意思是发送过响应不能再次发送响应
解决办法:res.json发送一次响应不能用res.send再次发送响应