koa框架11 ctx对象
res和req对象
ctx有四个这个对象,分别对应原生的对象和koa自己的对象,不过相对来说,都用的很少,因为koa对ctx对象内置很多属性就是req和res对象的属性,简化了调用。
ctx.req //原生的request对象
ctx.res //原生的response对象
ctx.request //koa自己的request对象
ctx.response //koa自己的response对象
其中我们之前使用的ctx.body其实就等于ctx.response.body
抛出异常
对于错误的处理,我们之前的方式是先设置ctx的status,再设置body,相对来说很麻烦。
koa提供了一个抛出异常的方法,并且这个异常错误对象和一般的error对象不同。
ctx.throw(401,"错误信息",error);
三个参数:
- 第一个为错误代码,num类型
- 错误信息,也就是body的内容
- 错误对象,你要给后台捕获的错误信息,自己设置的
使用了这个ctx.throw,代码会到此结束,不会再往下运行。他会直接将错误信息返回给前台。
但是如果我们在最上层使用了try捕获错误,那么由于这个方法会产生一个错误对象,他就会被捕获,从而无法返回信息给前台,如果需要返回的话,我们需要将catch捕获的错误对象e重新throw一下。
try {
}catch(e){
console.log(e);
throw e; //重新抛出
}
断言
断言一般用在那呢,就是我们可能会有一些情况,要求必须存在,比如,用户必须登录,这种情况我们一般是判断一个变量布尔值。
常用的方式就是使用if语句,再配合ctx.throw,但是这样就有点繁琐,koa提供了一个快速方法。
ctx.assert(变量,404,"错误信息",error);
assert这个比throw方法就多了个变量判断,如果变量不存在,就报错。
重定向
重定向分为两种,一种是301永久定向,一种302临时定向。
区别:
301会使浏览器产生缓存,第一次请求发现是301后,下次再请求就会直接跳转到缓存时要跳转的链接,如果你进行了修改,用户那边也不会发生变化,因为会优先使用缓存数据。
302是临时的,没有缓存,每次都要等服务器返回要跳转的链接才进行跳转。
ctx.redirect("/login");
koa的redirect默认是302跳转,如果你非要设置301,你可以手动设置status状态码为301
ctx.status = 301;
ctx.redirect("/login");
附件下载
附件下载,一般都是利用fs先读取文件,读取完毕后直接将这个二进制文件丢入body返回给浏览器,此时浏览器会触发下载。
router.get("/text", async ctx => {
ctx.body = await fs.readFile("./text.txt");
});
但是这样的话,文件的名字是很奇怪的,甚至连后缀都是没有的,所以我们要在下载前对这个文件名进行设置。
router.get("/text", async ctx => {
ctx.attachment("文件名.txt");
ctx.body = await fs.readFile("./text.txt");
});
使用attachment方法命名一个文件和后缀即可。
同步式下载
readFile虽然我们使用了异步的fs模块,但是他还是有一个弊端,就是他是一口气获取文件的全部内容,然后再将内容返回给浏览器。
假如我们有一个超大的文件,比如视频文件,好几个g,那么后端需要完全读取完这几个g的文件,才会发送给浏览器。
这样的性能就有很大的损失了,于是有了同步式的下载,服务器读多少,就传多少给浏览器,只需要把方法换一下就行了。
fs.createReadStream("./text.txt")
createReadStream替换原来的readFile即可。
内存流
如果对于一个需要动态生成的文件,并且这个文件特别大,使用fs就不现实了,我们需要安装一个内存流插件:memorystream
安装
npm i memorystream
const MemoryStream = require("memorystream");
router.get("/text", async ctx => {
ctx.attachment("文件名.txt");
const ms = new MemoryStream();
ctx.body = ms;
//写入数据
ms.write("第一条数据");
ms.write("第二条数据");
ms.write("第三条数据");
ms.end();
});
memorystream也是一个构造函数,我们new出后,赋值给body,然后通过write方法写入数据,写入完了end结尾。
头操作
后端对返回的内容设置头信息,除了设置原有的,还能自定义
获取:
ctx.headers["connection"]
ctx.get("connection")
这两种方式是等价的
修改:
ctx.set("connection",'xxxx');
有get就有set,set第二个参数就是要设置的信息。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
全部评论 2
一个小前端
Google Chrome Windows 10木灵鱼儿
FireFox Windows 10