目录
1.express优点(为什么有了http,还要express)
5.内置中间件Json和urlencoded中间件 static Router 错误中间件
5.koa-bodyParser获取Json和application/x-www-form-urlencoded
一.Express框架的基本使用
1.express优点(为什么有了http,还要express)
http对于路径和方法以及参数的处理麻烦,所有的内容都写在一块代码混乱 所以出现了框架
2.express的安装和初体验
1)express的安装:
第一种是脚手架:a.安装脚手架:npm install -g express-generator; b.创建项目:express 项目名 c.用vscode打开项目,npm install 安装依赖 d.npm start 启动
第二种方式是我们自己安装使用:创建文件夹 直接npm install express
3.什么是中间件,中间件能干什么
中间件本质是一个回调函数,回调函数一般可以传入三个参数 req代表请求头 res代表响应 next代表到下一个中间件
中间件内可以进行res和req的修改 结束请求,响应数据 以及传递到下一个请求头
4.自己编写的中间件
一般自己编写的中间件有四种类型 第一种是普通中间件 第二种是路径中间件 第三种是路径方法中间件 第四种是连续中间件 下面见实例:
const express=require('express')
const app=express()
// 普通中间件 普通中间件只要端口和hostname对了就都会进入
app.use((req,res,next)=>{
res.write('我是普通中间件')
next()
})
// 路径中间件
app.use('/user',(req,res,next)=>{
res.write('我是路径中间件')
next()
})
// 路径方法中间件
app.get('/user',(req,res,next)=>{
res.write('我是路径方法中间件')
next()
})
// 连续中间件
app.get('/user',(req,res,next)=>{
res.write('我是连续中间件')
next();
},(req,res,next)=>{
res.write('我是连续中间件')
res.end("返回数据")
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
5.内置中间件Json和urlencoded中间件 static Router 错误中间件
urlencoded中间件可以传入对象{ extended: true } true: 那么对urlencoded进行解析时, 它使用的是第三方库: qs false: 那么对urlencoded进行解析时, 它使用的是Node内置模块:querystring
const express=require('express')
const app=express()
app.use(express.json())
app.use(express.urlencoded())
app.post('/user',(req,res,next)=>{
console.log(req.body);//{ name: 'why', password: '11' }
res.end('结束')
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
Router的使用
const express=require('express')
const app=express()
const useRouter=express.Router()
useRouter.get("/",(req,res,next)=>{
res.end('222')
})
app.use('/user',useRouter)
app.listen('8888',()=>{
console.log('服务器启动成功');
})
错误中间件 next里面new一个错误就会传到错误中间件 错误中间件和普通的中间件就是多了一个参数err
const express=require('express')
const app=express()
app.get("/user",(req,res,next)=>{
next(new Error('发生了错误'))
})
app.use((err,req,res,next)=>{
console.log(err);
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
静态文件static 假如需要通过http://192.168.100.88:8888/1682269737163.png 访问
const express=require('express')
const app=express()
app.use(express.static('./wef/'))
app.listen('8888',()=>{
console.log('服务器启动成功');
})
5.第三方中间件:morgan multer
morgan 中间件:用来记录请求日志
const express=require('express')
const morgan=require('morgan')
const app=express()
const fs=require('fs')
// fs的流 用来写入信息到文件 flags是写入的方式 a+代表末尾写入
const stream=fs.createWriteStream('./log',{flags:'a+'})
// combined是日志格式 一般是这个格式 第二个参数是一个流对象
app.use(morgan('combined',{stream:stream}))
app.post('/user',(req,res,next)=>{
res.end('结束')
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
multer:文件上传中间件,不用文件上传中间件其实也可以做到接受文件,但是很多无用信息需要我们对传过来的buffer进行处理 这个中间件省去我们的处理过程 用法见下
一般我们会用第二种 因为第二种加上尾缀后图片就可以正确的显示啦
const express=require('express')
const multer=require('multer')
const path=require('path')
const app=express()
// 第一种用法 只传地址
// const upload=multer({
// dest:'./wef/'
// })
// 第二种用法 传入地址和自定义文件名字
const storage=multer.diskStorage({
destination:(req,file,cb)=>{
cb(null,'./wef/')
},
filename:(req,file,cb)=>{
cb(null,new Date().getTime()+path.extname(file.originalname))
},
})
const upload=multer({
storage
})
app.post('/user',upload.array('file'),(req,res,next)=>{
res.end('结束')
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
6.对于query和params
const express=require('express')
const app=express()
app.post('/user/:id',(req,res,next)=>{
console.log(req.params);//{ id: '23' }
console.log(req.query);//{ w: '12' }
res.end('结束')
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
7.响应服务器
res.write()可以写入内容 但是不结束请求
res.end()写入内容并且结束请求
res.status=相应码 返回相应码
const express=require('express')
const app=express()
app.post('/user/:id',(req,res,next)=>{
res.status=300
res.write('我是写入')
res.end('结束')
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
res.json 返回json 并且结束请求 可以传入对象 自动会转化为json
const express=require('express')
const app=express()
app.post('/user/:id',(req,res,next)=>{
res.status=300
res.json({a:2})
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
二.Koa框架的基本使用
1.框架的安装和基本使用
直接安装koa进行展示 对比express,中间件参数只有ctx和next 返回数据用ctx.body或者ctx.response.body 前面一个是后面一个的代理 还有一个区别是koa调用的时候需要先new一下
const koa=require('koa')
const app=new koa()
app.use((ctx,next)=>{
console.log('我是中间件');
ctx.body='11'
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
2.中间件
koa的中间件没有方法中间件也没有路径中间件 只有use中间件
3.koa-router路由
需要npm install koa-router
allowedMethods:app.use(usersRouter.allowedMethods()) 在 usersRouter 实例上加 allowedMethods,所有的接口都可以支持 options 请求了 比如:相应的返回 405(不允许), 和 501(没实现)
比如某接口没有写上 delete 方法,而用 delete 请求的话, 自动返回 405,代表不允许用该方法请求
而 501 是因为 koa 暂时只支持部分 http 方法, 一些使用较少的方法比如 link 方法请求就会返回 501 代表没实现这个方法
const koa=require('koa')
const app=new koa()
const router=require('koa-router')
// 需要new 传入一个对象value是路由名字 expree里面的路径不是这里传的 而是在use的时候传的
const useRouter= new router({prefix:'/user'})
useRouter.post('/',(ctx,next)=>{
ctx.body='12'
})
// 中间件是一个函数 useRouter.routes() express里面是不需要调用的
app.use(useRouter.routes())
app.listen('8888',()=>{
console.log('服务器启动成功');
})
4.获取params和query参数
ctx.request.query和ctx.query是一样的 他们是代理的关系
const koa=require('koa')
const app=new koa()
const router=require('koa-router')
const useRouter= new router({prefix:'/user'})
useRouter.post('/:id',(ctx,next)=>{
console.log(ctx.query);// { w: '12' }
console.log(ctx.params);//{ id: '23' }
console.log(ctx.request.query);// { w: '12' }
console.log(ctx.request.params);//{ id: '23' }
ctx.body='12'
})
app.use(useRouter.routes())
app.listen('8888',()=>{
console.log('服务器启动成功');
})
5.koa-bodyparser获取Json和application/x-www-form-urlencoded
const koa=require('koa')
const app=new koa()
const bodyed=require('koa-bodyparser')
app.use(bodyed())
app.use((ctx,next)=>{
// 当取body的时候就不能ctx.body来取了 因为这是中间件做了处理的内容
console.log(ctx.request.body);//{ name: 'why', password: '11' }
ctx.body='12'
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
6.koa-multer
const koa=require('koa')
const app=new koa()
const path=require('path')
const multer=require('koa-multer')
const storage=multer.diskStorage({
destination:(req,file,cb)=>{
cb(null,'./ww/')
},
filename:(req,file,cb)=>{
// 传入得文件需要不能只new Date()
cb(null,new Date().getTime()+path.extname(file.originalname))
},
})
// 第一种文件上传方式
// 如果没有该文件 启动服务器的时候就会给你主动生成
// const upload=multer({
// dest:'./ww/'
// })
// 第二种文件上传方式
const upload=multer({
storage
})
// 当没有路由的时候只能单独use
app.use(upload.array('file'))
app.use((ctx,next)=>{
ctx.body='响应消息'
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
7.koa-static
const koa=require('koa')
const app=new koa()
// 下载包
const static=require('koa-static')
// 指定静态文件夹
app.use(static('./ww/'))//也可以是./ww
app.use((ctx,next)=>{
ctx.body='响应消息'
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
8.错误中间件
const koa=require('koa')
const app=new koa()
app.use((ctx,next)=>{
ctx.body='响应消息'
//用ctx.app emit一个错误 会到错误中间件
ctx.app.emit('error','我是错误',ctx)
//app.emit('error','我是错误',ctx) 也行
})
// 注意这里是on对其监听 不是use
app.on('error',(err,ctx)=>{
console.log(err,1111);
})
app.listen('8888',()=>{
console.log('服务器启动成功');
})
9.数据的响应
const Koa = require('koa');
const app = new Koa();
app.use((ctx, next) => {
// 设置内容
// ctx.response.body
// ctx.response.body = "Hello world~"
// ctx.response.body = {
// name: "coderwhy",
// age: 18,
// avatar_url: "https://abc.png"
// };
// 设置状态码
// ctx.response.status = 400;
// ctx.response.body = ["abc", "cba", "nba"];
// ctx.response.body = "Hello World~";
ctx.status = 404;
ctx.body = "Hello Koa~";
});
app.listen(8000, () => {
console.log("koa初体验服务器启动成功~");
});
三.对这两种框架的对比和思考
1.koa只剩下了普通中间件,在实际开发中,我们都会用router去配置,所以express的这些中间件显得有点多余
2.中间件的参数ctx合并了res和req,并且对request做映射,这可以在书写的时候看上去更加简洁
3.koa不管是创建服务器还是koa-router都采用了面向对象,而express是面向函数,面向对象更易维护、易复用、易扩展
4.koa的路由在创建的时候就传入了路径,这样做可以把路径更好的分离在路由文件中
5.kuo的错误处理,采用了发出事件和监听事件的形式,对于express,错误都直接到错误中间件来说,我们可以更好的给错误进行分类,也可以用这个做其他的操作,显然是更具有灵活性和代码简洁
思考:对于路径./为什么和想象的有时候不一样