node 搭建基于 koa 的简单服务

Koa 是基于 node.js 平台平台的 web 开发框架,如今也被广泛地运用,中文官方地址:Koa

本文将介绍 Koa 的简单应用,并且依托 Koa 搭建一个简单的 web 服务

首先,我们需要先通过 npm i koa 安装 koa,然后在项目中引入:

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

app.use(async (ctx) => {
  ctx.body = "Hello World";
});

app.listen(3000);

配置模板引擎

如下:

//配置模板引擎
//引入koa-views  并且配置模板引擎
const views = require("koa-views");
app.use(
  views("views", {
    // 模板放在views文件夹中,当调用 await ctx.render('index') 则到views文件夹中去对应的模板
    extension: "ejs", //这样配置,模板的后缀名是ejs
  })
);

app.use(
  views("views", {
    map: { html: "ejs" }, //这样配置,模板的后缀名是html,模板引擎是ejs
  })
);

session 与 cookies

要在 koa 中使用session,需要先引入koa-session,设置 app.keys 作为 session 对应 cookie 的签名,如下配置:

// 引入 koa-session
const session = require("koa-session");
//配置session中间件
app.keys = ["some secret hurr"]; // cookie的签名
const CONFIG = {
  key: "koa:sess", // cookie 的key(session_id是储存在cookie中的)
  maxAge: 846400000, //  过期时间
  overwrite: true,
  httpOnly: true, // true 表示只有服务器端可以获取cookie
  signed: true, // 默认 签名
  rolling: false, // 表示每次访问都重新设置
  renew: false, // 当用户访问时,快要过期时重设
};
app.use(session(CONFIG, app));

要在 koa 中使用cookies,则直接通过ctx.cookies.set()ctx.cookies.get()使用即可,如下:

//设置cookies
ctx.cookies.set("userinfo", "lili", {
  maxAge: 60 * 1000 * 60, // 经过多长时间过期
  path: "/news", // 配置可以访问的地址,只有对应的路由地址可以访问
  /*
        domain:'.baidu.com' ,            // 配置可以访问的域名,默认是当前域可以访问
        httpOnly:true                // true 表示这个cookie只有服务器端可以访问,false 表示客户端也可以访问
        */
});

//设置中文的cookie , 使用base64编码
let username = new Buffer("马玉祥").toString("base64");
ctx.cookies.set("username", username, {
  maxAge: 60 * 1000 * 60,
});

//获取cookies
let username_cookie = ctx.cookies.get("username");

获取 post 数据

原始方法中,我们需要先封装一个异步方法接收数据:

exports.getPostData = function (ctx) {
  //获取数据,异步

  return new Promise((resolve, reject) => {
    try {
      let str = "";
      ctx.req.on("data", (chunk) => {
        str += chunk;
      });

      ctx.req.on("end", (chunk) => {
        resolve(str);
      });
    } catch (err) {
      reject(err);
    }
  });
};

然后在 koa 中使用:

//原生node.js方法 :
var common = require("./module/common.js"); //封装的异步方法,返回的是一个Promise
router.post("/post_form", async (ctx) => {
  //获取表单数据
  var data = await common.getPostData(ctx);

  console.log(data);
  ctx.body = data;
});

而我们可以通过bodyparser中间件更轻松地实现:

//使用koa中的bodyparser中间件获取post表单的数据 :
//引入并配置
var bodyParser = require("koa-bodyparser");
app.use(bodyParser());
//在路由匹配中使用
router.post("/post_form_koa", async (ctx) => {
  //获取表单数据
  let data = ctx.request.body;

  console.log(data);
});

静态资源服务

通常,将静态资源放在 static 文件夹中,然后通过以下配置静态文件:

//koa-static 静态web服务
const static = require("koa-static");
app.use(static(__dirname + "/static")); // 到static目录中去找对应静态文件  请求的url不用包含static,如 href='css/basic.css'

//也可以配置多个静态服务对应的文档,则静态资源可以分别放在不同的文件夹
app.use(static(__dirname + "/public"));

中间件

中间件的使用在 node 中十分重要,用好中间件可以极大提高我们的开发效率以及项目的性能
中间件通过app.use(async (ctx,next)={...}) 的方式定义,ctx是当前请求的上下文,包含当前信息,而next则是定义继续向下匹配中间价以及路由,在中间件中一定要调用await next()

//配置中间件,把公共的数据放到ctx.state中,则公共数据可在所有模板中使用
app.use(async (ctx, next) => {
  ctx.state = {
    username: "li_car",
    age: 19,
  };

  await next();
});

// 中间件的使用
// 中间件类似于捕获冒泡形式依次触发,如果不执行 await next() 则不会继续向下匹配中间件或路由,在该中间件终止程序
app.use(async (ctx, next) => {
  console.log("中间件01");
  await next();

  if (ctx.status == 404) {
    ctx.status = 404;
    ctx.body = "路由错误,404";
  } else {
    console.log("匹配到路由之后再执行到这里,这里是中间件01");
  }
});

app.use(async (ctx, next) => {
  console.log("中间件02");
  await next();

  console.log("匹配到路由之后再执行到这里,这里是中间件02");
});

配置路由

配置匹配路由的操作,通过以下方式:

var Router = require("koa-router");
var router = new Router();

//  配置路由
// ctx  上下文context,包含了req,res等信息
router
  .get("/", async (ctx) => {
    //设置cookies
    ctx.cookies.set("userinfo", "lili", {
      maxAge: 60 * 1000 * 60, // 经过多长时间过期
      path: "/news", // 配置可以访问的地址,只有对应的路由地址可以访问
      /*
        domain:'.baidu.com' ,            // 配置可以访问的域名,默认是当前域可以访问
        httpOnly:true                // true 表示这个cookie只有服务器端可以访问,false 表示客户端也可以访问
        */
    });

    //设置中文的cookie , 使用base64编码
    let username = new Buffer("马玉祥").toString("base64");
    ctx.cookies.set("username", username, {
      maxAge: 60 * 1000 * 60,
    });

    //设置session
    ctx.session.user = "张三";

    ctx.body = "首页"; //返回数据,相当于原生里的res.writeHead  res.end()
  })
  .get("/news", async (ctx) => {
    //获取cookies
    let userinfo = ctx.cookies.get("userinfo");
    console.log(userinfo);

    //获取设置了base64编码的cookie
    let username_cookie = ctx.cookies.get("username");
    let username = new Buffer(username_cookie, "base64").toString();
    console.log(username);

    //获取session
    console.log(ctx.session.user);

    ctx.body = "这是一个新闻界面";
  })
  .get("/packages", async (ctx) => {
    //    ctx.query   获取到 url? 后传的query值      ctx.querystring 则获取到query字符串
    let query = ctx.query;
    console.log(query);

    ctx.body = "packages";
  })
  .get("/pages/:id/:comment", async (ctx) => {
    //    ctx.params  获取到 动态路由事先设置好的占位符值, :id 这样的形式设置动态路由占位符
    let params = ctx.params;
    console.log(params);

    ctx.body =
      "pages    " + String(params.id) + "     " + String(params.comment);
  });

启动服务

设置好路由后,需要启动路由并且监听端口,如下:

//启动路由
app
  .use(router.routes()) //启动路由
  .use(router.allowedMethods()); //如果出错了,根据status自动设置响应头

//监听端口
app.listen(8081);
console.log("Server running at http://127.0.0.1:8081/");

结语

本文介绍 koa 的基础用法,供参考

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容