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);

三个参数:

  1. 第一个为错误代码,num类型
  2. 错误信息,也就是body的内容
  3. 错误对象,你要给后台捕获的错误信息,自己设置的

使用了这个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第二个参数就是要设置的信息。

分类: Node 标签: nodekoactx

评论

全部评论 2

  1. 一个小前端
    一个小前端
    Google Chrome Windows 10
    await fs.readFile是同步方法、会出问题需要需要使用readFileSync
    1. 木灵鱼儿
      木灵鱼儿
      FireFox Windows 10
      @一个小前端我觉得带sync才是同步方法啊[tv_doge]

目录