koa知识点

koa基本使用

npm i koa
const koa = require('koa')

const app = new koa()

// 中间件1
app.use((ctx,next)=>{
  ctx.body = 'hi1'
  next()
})

// 中间件2
app.use((ctx,next)=>{
  ctx.body = 'hi2'
  next()
})

// 中间件3
app.use((ctx,next)=>{
  ctx.body = 'hi3'
  next()
})

app.listen(8080, () => {
  console.log('http://localhost:8080');
})

ctx上下文对象

  1. ctx.request和ctx.response 是Koa 封装的对象
  2. ctx.req和ctx.res 是Node.js 封装的对象,有HTTP请求对象的所有属性和方法
  3. next函数返回Promise对象,故可以使用同步的方式接收异步代码

跨域

const cors = require('koa2-cors');
app.use(cors())

路由

npm i @koa/router
const koa = require('koa')
const KoaRouter = require('@koa/router')

const app = new koa()

// 1.创建路由对象
const userRouter = new KoaRouter({ prefix: '/users' })

// 2.在路由中注册中间件
userRouter.get('/', (ctx, next) => {
  ctx.body = "获取get"
})

// 3.使路由生效
app.use(userRouter.routes())
app.use(userRouter.allowedMethods())

app.listen(8080, () => {
  console.log('http://localhost:8080');
})

allowedMethods的作用:用于判断某一个method是否支持
(1). 如果我们请求 get,那么是正常的请求,因为我们有实现get;

(2). 如果我们请求 put、delete、patch,那么就自动报错:Method Not Allowed,状态码:405;

(3). 如果我们请求 link、copy、lock,那么久自动报错:NotImplemented,状态码:501;

参数解析

query、params参数

const koa = require('koa')
const KoaRouter = require('@koa/router')

const app = new koa()

const userRouter = new KoaRouter({ prefix: '/users' })

// params参数
// http://localhost:8080/users/1
userRouter.get('/:id', (ctx, next) => {
  ctx.body = ctx.params.id
})

// query参数
// http://localhost:8080/users?id=1&name=cjc
userRouter.get('/', (ctx, next) => {
  ctx.body = ctx.query
})

app.use(userRouter.routes())
app.use(userRouter.allowedMethods())

app.listen(8080, () => {
  console.log('http://localhost:8080');
})

json、x-www-form-urlencoded

npm i koa-bodyparser
const koa = require('koa')
const KoaRouter = require('@koa/router')
const bodyParser = require('koa-bodyparser')

const app = new koa()

const userRouter = new KoaRouter({ prefix: '/users' })

// 解析json、x-www-form-urlencoded的中间件
app.use(bodyParser())

// json、x-www-form-urlencoded参数
userRouter.post('/', (ctx, next) => {
  ctx.body = ctx.request.body
})

// 使用路由
app.use(userRouter.routes())
app.use(userRouter.allowedMethods())

app.listen(8080, () => {
  console.log('http://localhost:8080');
})

form-data

npm i @koa/multer multer
const koa = require('koa')
const KoaRouter = require('@koa/router')
const multer = require('@koa/multer')

const app = new koa()

const userRouter = new KoaRouter({ prefix: '/users' })

// multer() -> 返回multer实例
// formDataParse.any() -> 返回中间件
const formDataParse = multer()

// form-data参数
userRouter.post('/', formDataParse.any(), (ctx, next) => {
  ctx.body = ctx.request.body
})

app.use(userRouter.routes())
app.use(userRouter.allowedMethods())

app.listen(8080, () => {
  console.log('http://localhost:8080');
})

文件上传

npm i @koa/multer multer
const koa = require('koa')
const KoaRouter = require('@koa/router')
const multer = require('@koa/multer')

const app = new koa()

/**
 * 文件上传
 */
const uploadRouter = new KoaRouter({ prefix: "/upload" });

const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, cb) {
      cb(null, "./imgs"); //指定存储文件夹为 imgs
    },
    filename(req, file, cb) {
      // 解决中文名乱码的问题
      file.originalname = Buffer.from(file.originalname, "latin1").toString(
        "utf8"
      );
      cb(null, Date.now() + "_" + file.originalname);
    },
  }),
});

// 单文件上传
uploadRouter.post("/singleFile", upload.single("photo"), (ctx, next) => {
  ctx.body = ctx.request.file;
});

// 多文件上传
uploadRouter.post("/multiFiles", upload.array("photos"), (ctx, next) => {
  ctx.body = ctx.request.files;
});

app.use(uploadRouter.routes());
app.use(uploadRouter.allowedMethods());

app.listen(8080, () => {
  console.log('http://localhost:8080');
})

总结

const koa = require("koa");
const KoaRouter = require("@koa/router");
const bodyParser = require("koa-bodyparser");
const multer = require("@koa/multer");
const static = require("koa-static");
const app = new koa();

/**
 * 全局中间件
 */
// 1.跨域
// 2.普通全局中间件
app.use(bodyParser());

/**
 * 路由中间件,参数解析
 */
const userRouter = new KoaRouter({ prefix: "/users" });

// query、params
userRouter.get("/:id", (ctx, next) => {
  const { params, query } = ctx;
  ctx.body = {
    params: params,
    query: query,
  };
});

// json、x-www-form-urlencoded
userRouter.post("/addUser", (ctx, next) => {
  ctx.body = ctx.request.body;
  console.log(ctx.req.body, ctx.request.body);
});

// form-data
const formDataParse = multer();
userRouter.post("/addUserByForm", formDataParse.any(), (ctx, next) => {
  ctx.body = ctx.request.body;
});

app.use(userRouter.routes());
app.use(userRouter.allowedMethods());

/**
 * 文件上传
 */
const uploadRouter = new KoaRouter({ prefix: "/upload" });

const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, cb) {
      cb(null, "./imgs"); //指定存储文件夹为 imgs
    },
    filename(req, file, cb) {
      // 解决中文名乱码的问题
      file.originalname = Buffer.from(file.originalname, "latin1").toString(
        "utf8"
      );
      cb(null, Date.now() + "_" + file.originalname);
    },
  }),
});

// 单文件上传
uploadRouter.post("/singleFile", upload.single("photo"), (ctx, next) => {
  ctx.body = ctx.request.file;
});

// 多文件上传
uploadRouter.post("/multiFiles", upload.array("photos"), (ctx, next) => {
  ctx.body = ctx.request.files;
});

app.use(uploadRouter.routes());
app.use(uploadRouter.allowedMethods());

// 静态服务器
app.use(static("./imgs"));

app.listen(8080, () => {
  console.log("http://localhost:8080");
});

静态资源

npm i koa-static 
const koa = require('koa')
const static = require('koa-static')

const app = new koa()

// 静态服务器
// http://localhost:8080/[imgs文件夹下的文件名] 访问静态资源
// http://localhost:8080/1691313647439_labi.jpg
app.use(static('./imgs'))

app.listen(8080, () => {
  console.log('http://localhost:8080');
})

错误处理和数据响应

数据响应

响应体ctx.body的类型:

  1. string
  2. Buffer
  3. Stream
  4. Object || Array
  5. null 不响应任何内容

ctx.status未设置任何内容,Koa自动将状态设置为200或204(no content)

const koa = require("koa");
const KoaRouter = require("@koa/router");
const fs = require("fs");
const app = new koa();

const userRouter = new KoaRouter({ prefix: "/users" });

userRouter.get("/", (ctx, next) => {
  // // 1.string
  // ctx.body = "ok";

  // // 2.Object || Array
  // ctx.body = {
  //   name: "ccc",
  //   age: 999,
  // };

  // // 3.Buffer
  // ctx.body = Buffer.from("Buffer数据");

  // 4.Stream 流数据
  const readStream = fs.createReadStream("./imgs/1691313647439_labi.jpg");
  ctx.type = "image/jpeg";
  ctx.body = readStream;

  // 5.null
  // ctx.body = null;
});

app.use(userRouter.routes());
app.use(userRouter.allowedMethods());

app.listen(8080, () => {
  console.log("http://localhost:8080");
});

错误处理

  1. 抛出自定义错误事件 ctx.app.emit(eventName,…args), 第一个参数为监听器的名称,第二个为不定参数
  2. app.on(“eventName”, (errCode, ctx) => {}) ,回调函数中的参数,均为emit中传递过来的
const koa = require("koa");
const KoaRouter = require("@koa/router");
const bodyParser = require("koa-bodyparser");
const app = new koa();

const userRouter = new KoaRouter({ prefix: "/users" });
app.use(bodyParser());

userRouter.post("/login", (ctx, next) => {
  const { name, pwd } = ctx.request.body;
  if (!name || !pwd) {
    // 1.抛出自定义错误事件error
    ctx.app.emit("error", -1001, ctx);
  } else if (name !== "ccc" || pwd !== 123) {
    ctx.app.emit("error", -1002, ctx);
  } else {
    ctx.body = {
      code: 0,
      msg: "登录成功",
      token: "xxx",
    };
  }
});

app.use(userRouter.routes());
app.use(userRouter.allowedMethods());

// 2.监听事件,统一错误处理
app.on("error", (code, ctx) => {
  let msg = "未知错误";
  switch (code) {
    case -1001:
      msg = "账号或密码为空";
      break;
    case -1002:
      msg = "账号或密码错误";
      break;
    default:
      break;
  }

  ctx.body = {
    code,
    msg,
  };
});

app.listen(8080, () => {
  console.log("http://localhost:8080");
});

Koa执行同步、异步代码

洋葱模型(U型)

Koa的中间件机制:

  1. 遇到next或者 await next就中断本中间件的代码执行,跳转到对应的下一个中间件执行期内的代码,一直到最后一个中间件
  2. 然后逆序回退到倒数第二个中间件await next 或者next下部分的代码执行,完成后继续回退,一直回退到第一个中间件await next或者next下部分的代码执行完成,中间件全部执行结束。
  3. Koa 是在所有中间件中使用 ctx.body 设置响应数据,但是并不会立即响应,而是在所有中间件执行结束后,再调用 res.end(ctx.body) 进行响应

洋葱模型:请求与响应都在最外层,中间件处理是一层层进行。

同步代码

const koa = require("koa");
const app = new koa();

// Koa执行同步代码
app.use((ctx, next) => {
  console.log("middleware1");
  ctx.msg = "aaa";
  next();

  ctx.body = ctx.msg;
});

app.use((ctx, next) => {
  console.log("middleware2");
  ctx.msg += "bbb";
  next();
});

app.use((ctx, next) => {
  console.log("middleware3");
  ctx.msg += "ccc";
});

app.listen(8080, () => {
  console.log("http://localhost:8080");
});

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

异步代码

  1. next前不加await
    如果执行的下一个中间件是一个异步函数, 那么next默认不会等到中间件的结果, 就会执行下一步操作

  2. next前加await
    koa中的next()返回Promise对象,故可以等待异步代码执行结果
    express中的next()返回void

const koa = require("koa");
const app = new koa();

function asyncFoo() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("bbb");
    }, 1000);
  });
}

// Koa执行异步代码
app.use(async (ctx, next) => {
  console.log("middleware1");
  ctx.msg = "aaa";
  await next();

  ctx.body = ctx.msg;
});

app.use(async (ctx, next) => {
  console.log("middleware2");
  const res = await asyncFoo();

  ctx.msg += res;

  await next();
});

app.use((ctx, next) => {
  console.log("middleware3");
  ctx.msg += "ccc";
});

app.listen(8080, () => {
  console.log("http://localhost:8080");
});

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node.js是一个基于Chrome V8引擎的JavaScript运行环境,用于构建高性能、可扩展的网络应用程序。它允许我们在服务器端使用JavaScript编写和运行代码,并且具有以下重要的知识点: 1. 异步编程:Node.js采用非阻塞I/O模型,通过事件驱动和回调函数实现异步编程。这使得可以处理大量并发请求而不会阻塞应用程序。 2. 模块化:Node.js支持模块化开发,通过模块系统可以将代码分割成小的、可复用的模块。内置的模块系统提供了大量的核心模块,同时也可以使用第三方模块。 3. 事件驱动:Node.js使用事件驱动的架构,通过触发和监听事件来实现异步处理。核心模块`events`提供了事件的处理能力。 4. 文件系统操作:Node.js提供了对文件系统的操作能力,可以读写文件、创建和删除目录等。核心模块`fs`用于处理文件系统相关操作。 5. 网络通信:Node.js可以创建网络服务器和客户端,通过核心模块`http`和`https`实现HTTP和HTTPS协议的通信。 6. 第三方库和框架:Node.js拥有庞大的第三方库和框架生态系统,如Express.js、Koa.js、Socket.io等,可以加速开发过程。 7. 数据库连接:Node.js可以连接各种数据库,如MySQL、MongoDB、PostgreSQL等。通过相应的驱动程序或ORM框架,可以实现与数据库的交互。 8. 安全性:Node.js有一些内置的安全机制,如防止跨站脚本攻击(XSS)和SQL注入攻击。同时也可以使用第三方模块增强安全性。 这些是Node.js的一些重要知识点,希望对你有帮助!如果你还有其他问题,可以继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值