Koa框架 一个http框架
Koa其实就是对node原生http对象的二次包装,提供了更好的接口和结构,方便使用和维护。
具体API https://koa.bootcss.com/
Koa本身超级简单,也没自带路由,可以借助别人实现的第三方中间件,来配合使用。
例如路由 : koa-router
第三方中间件大全:https://github.com/koajs/koa/wiki
常用:
koa-static-cache 静态资源代理
koa-router 路由
nunjucks 模板引擎
koa2-cors 解决跨域问题
在服务器端app.js
const cors = require(‘koa2-cors’);
app.use(cors()); //放在route前
app.use(router.routes());
1 | const Koa = require('koa');//可确认下koa版本是否是2 |
Koa帮我们重新包装了http对象(包成app对象),并处理了很多通用数据和方法,并把这些数据和方法挂到了app的一个属性下面==app.context== context为了方便一般可简写为ctx
没有请求的时候打印(直接打印只能用dir)app.context 是空对象,还没有数据过来
==一般不会直接调用app.context,因为该对象没有经过处理,而是要通过中间件函数的第一个参数去掉用==
有请求的时候,中间件函数就会执行,同时Koa会解析数据并赋值给app.context,把它作为当前执行的中间件的第一个参数传入进来
这样使用:
app.use(ctx=>{console.log(ctx)})
context下包含的对象,请求响应两大对象 就同http一样
- request对象
- response对象 |响应(输出)|
- app对象
context对象下还有一些属性是request和response的映射
e.g
context.response.body === context.body
context.request.header === context.header
为了写起来简便,很多request和response下的对象都直接挂在了context下。
==注意==
ctx.body是ctx.response.body 是响应的正文,是服务器发给客户端的!
ctx.request.body 并不一样 这是请求的正文,是客户端发给服务器的!
context.request.url
context.response.body = “
hello
”|“{a:1,b:2}”|“hello world”帮你自动辨别你提供的数据,智能地设置content-type为html/json/plain (相当于MIME),不用麻烦你自己再判断
中间件的内涵
一个http服务器主要做的事情流程是如何的?
- 解析请求 -> 处理数据 -> 返回数据
Koa框架帮助我们处理第一步的请求解析并封装到app对象里面以供后续使用且同时帮我们处理数据的返回,比如根据处理好的数据返回不一样的Content-Type
中间的步骤是数据处理,数据的处理就和业务是相关的(你有什么具体需求Koa肯定不知道的),Koa就无能为力了
中间件
==中间件可以理解为对用户请求进行处理(或过滤等)的一个东西,不会直接对前端进行响应,而是将处理结果往下传递,就是中间处理数据的一个部件==
需要我们处理的步骤在中间(处理数据这个步骤),那么我们只需要通过某种方式把我们需要的事情注册到Koa中间件的列表中,当Koa处理完成解析请求后,就会自动的执行我们注册的中间件,执行完中间件后就会自动调用返回数据的代码
深度理解中间件的执行顺序,next的作用
https://segmentfault.com/q/1010000011033764
洋葱圈模型,这个也可以适用于事件冒泡机制啊哈哈
一个js文件里头 不是所有有use的地方 都需要看到next 没有next就影响其他use了 ==并不是!==
这个函数得是中间件 你才需要next! 比如访问静态页面或访问路由 不需要向下next了 就不算中间件?
中间件本质就是一个函数
注册中间件
app.use(function(){
});
//可以处理代理、跨域、负载等各种各样的问题 ssr服务器端渲染
中间件的next方法是异步的,需要加上await
Koa解决跨域简单写法
app.use( async (ctx,next) => {
ctx.set(‘Access-Control-Allow-Origin’,‘*’); await next();
})
中间件模拟 深度
https://segmentfault.com/a/1190000016707059
Koa框架应用
==路径开头的斜线非常非常重要==
静态资源代理 koa-static-cache
某些特定路径 走静态资源代理
其他路径 走服务器路由逻辑
需要访问静态资源时(例如html啊 图片啊之类)使用静态资源代理 否则打开服务器它不知道读哪个目录 想把目录当成一个服务器 访问里头的静态资源 就需要做这一步
否则读不到静态资源
切记: 访问时要正确路径/xxx.html 千万别漏了(动态路由不需要,这儿静态的千万别弄错)
dir设置静态资源所在目录 要加.
prefix设置你想要加的前缀 不设置也行的 不加.
访问动态资源可使用路由koa-router 配合前端的get请求的url
KoaStaticCache(dir[,options][,files]) 包装函数写法 返回一个函数
dir:指定要处理的静态文件(html)存放目录,当用户访问某个url时
options为对象,可以修改
max-age 最长缓存时间| 是否压缩(gzip) | 前缀(prefix,设置url前缀) | dynamic(是否动态读取)
例如prefix:/public 则需要请求/public/index.html才可以访问
prefix的作用是 可以区分开静态资源和需要动态处理的资源 加上前缀才可以正常访问
dynamic 是否动态读取,默认为false
accept-encoding为支持的编码(gzip更常用)
访问同一个url时
静态资源: 如果资源内容不改变,那么访问这个url得到的内容不会有任何变化
例如css啊 图片啊 部分js代码(特效之类)等
动态资源: 同一个url可能会根据不同的处理得到==不一样==的内容
举个栗子🌰 ctx.body = “”+Math.random() 每次访问同一个url得到的内容可能都不一样
静态资源可以利用直接读取文件并返回的方式处理,例如利用koa-static-cache
动态资源需要具体的处理逻辑,根据不同的url返回不一样的内容
动态资源的url可能量也很大,为了更好地处理这些动态资源url,我们需要使用==路由==,例如koa-router
==Koa框架帮我们处理了请求,处理了输出==
向客户端返回数据是通过 http=> end()方法来实现的
把ctx.body作为返回值, 相当于.end(ctx.body)
所以不需要在中间件中手动调用end方法,只需要给ctx.body赋值
然而中间件很多都是异步操作,如果不做特殊操作 .end方法不会等异步操作完成才调用,所以那时调用会是 not found (那时ctx.body是undefined)
如果 await fn(); .end(ctx.body); 这样就会等fn执行有结果后 才会调end
路由 koa-router
路由:即映射,内容分发,一个url与某个函数的绑定 形成一种关系
为我们的url 绑定对应的 处理函数
1 | router.use('/',ctx=>{}) |
💡注意
多个中间件函数只会默认执行第一个,后续的中间件函数需要我们手动调用
中间件函数的第二个参数是一个next方法,调用该方法就可以执行下一个匹配的中间件
d
router.use(‘/user’,(ctx,next)=>{
//判断
next();
})
redirect方法 重定向(不设置默认为302) | 重定向分为 301永久重定向 , 302临时重定向
router.redirect(‘/login’,‘/login1’,302); //临时设置login重定向到login1,参数也可以设置为301
prefix设置前缀,省去后面重复写的时候麻烦
const router = new KoaRouter({
prefix: “/user”
});
==path-to-regexp==
/:id 表示/后面面的值是不固定的,所有符合
温习下2小时处视频内容,模板字符串,对象解构,find用法等知识点,
模板字符串支持表达式,不支持语句
可以这么写${users.map(user=>\
nunjucks 模板引擎
渲染工作是在后端进行的
let str = tpl.renderString(‘
Hello
’,{username:xxxx}) 代表变量 类似es6中的${var}管道符| 管道符前的内容作为参数传给管道符后的函数 例如
文件上传模块 koa-multer
storage配置
封装的file属性 fieldname | originalname | encoding | mimetype
