Koa2快速入门上手

Koa2 快速入门上手

Koa2 快速开始

Koa2 路由


Koa2 快速开始

  • 环境准备

    • 由于 Koa 中使用的是 async/await 的语法,所有需要 NodeJS 的版本在 7.6.0 以上,注:7.6.0 开始完全支持 async/await
    • npm 版本需要 3.x 以上
  • 编写 Koa2 的第一个 Demo

    • 创建一个 quick-start 文件夹作为项目文件夹

      mkdir quick-start && cd quick-start
    • 初始化项目并安装 koa

      # 初始化项目,填写相应信息
      yarn init
      
      # 安装 koa
      yarn add koa
      
      # 创建一个 index.js
      touch index.js
    • 编写一个 Koa 程序

      const Koa = require("koa");
      
      const app = new Koa();
      
      app.use(async (ctx) => {
          ctx.body = "Hello Koa2!";
      });
      
      app.listen(8080, () => {
          console.log("The Server Start At Port 8080 !");
      });
    • 启动项目并查看结果

      node index.js

      打开浏览器访问 http://localhost:8080/ ,效果如下:

      Koa2第一个Demo程序

  • async/await 的特点

    • 可以使异步逻辑用同步写法实现
    • 最底层的 await 返回需要是 Promise 对象
    • 可以解决传统的回调地狱问题
  • Koa 结构简析

    • Koa 源码地址: https://github.com/koajs/koa
    • Koa 源码在项目的 lib 文件夹下,我们可以看到有四个文件
      • application.js:整个 Koa 的入口文件,封装了 contextrequestresponse 以及最核心的中间件处理流程
      • context.js:处理应用上下文,里面直接封装部分 request.js 和 response.js 的方法
      • request.js:处理 http请求
      • response.js:处理 http响应
    • Koa 的特性
      • 只提供封装好了 http上下文请求响应 以及基于 async/await 的中间件容器
      • 利用 ES7 的 async/await 来处理传统的回调嵌套问题以及替代 generator函数
      • 中间件只支持使用 async/await 封装的中间件,如果使用 generator函数 中间件,需要通过 koa-convert 封装一下才可使用
  • 编写 Koa 中间件

    • 使用 generator函数 编写中间件

      • 中间件代码

        # logger-generator.js
        function log(ctx) {
            console.log(ctx.method, ctx.header.host + ctx.url);
        }
        
        module.exports = function() {
            return function*(next) {
                // 执行中间件的操作
                log(this);
        
                if (next) {
                    yield next;
                }
            };
        };
        
      • 在 Koa1 中编写中间件

        # index.js
        const Koa = require("koa");
        const logger = require("./middleware/logger-generator");
        
        const app = new Koa();
        
        app.use(logger());
        
        app.use(function*() {
            ctx.body = "Hello Koa1 Gneerator";
        });
        
        app.listen(8080, () => {
            console.log("The Server Start At Port 8080 !");
        });
        
      • 在 Koa2 中编写中间件

        # 安装 koa-convert
        yarn add koa-convert
        # index.js
        const Koa = require("koa");
        const convert = require("koa-convert");
        const logger = require("./middleware/logger-generator");
        
        const app = new Koa();
        
        app.use(convert(logger()));
        
        app.use(ctx => {
            ctx.body = "Hello Koa2 Gneerator";
        });
        
        app.listen(8080, () => {
            console.log("The Server Start At Port 8080 !");
        });
        
    • 使用 async/await 编写中间件

      • 中间件代码

        module.exports = (ctx, next) => {
            console.log(
                "logger async middleware",
                ctx.method,
                ctx.header.host + ctx.url
            );
        
            next();
        };
      • 使用中间件

        const Koa = require("koa");
        const logger = require("./middleware/logger-async");
        
        const app = new Koa();
        
        app.use(logger);
        
        app.use(async (ctx) => {
            ctx.body = "Hello Koa Async Middleware!";
        });
        
        app.listen(8080, () => {
            console.log("The Server Start At Port 8080 !");
        });

Koa2 路由

  • Koa 原生路由

    路由指的就是我们请求的 URL 地址,Koa 的 url 存储在 ctx.request 对象中;我们看如下的代码:将请求的 url 地址,显示在浏览器中

    const Koa = require("koa");
    
    const app = new Koa();
    
    app.use((ctx) => {
        const url = ctx.request.url;
        ctx.body = { url };
    });
    
    app.listen(3000, () => {
        console.log("The server running at: http://localhost:3000/");
    });
    
    // 浏览器访问: http://localhost:3000/users
    // 返回: { url: '/users' }
    
    // 浏览器访问: http://localhost:3000/hello/world
    // 返回: { url: '/hello/world' }
    
    // 读者可自己多测试一些url
    • 定制化路由

      • 创建一个文件夹作为项目目录, 并初始化项目、安装依赖

        mkdir custom-router && cd custom-router
        yarn init -y
        yarn add koa
      • 新建 index.js 文件,作为项目的主入口文件

      • 创建 views 文件夹,作为视图文件的根目录。分别新建 not-found.htmlusers.htmltodo.htmlindex.html

      • 编写路由处理核心代码:

        const Koa = require("koa");
        const path = require("path");
        const fs = require("fs");
        
        const app = new Koa();
        
        /**
         * 使用Promise封装文件读取函数
         * @param {string} page 文件名称(包含后缀名)
         */
        const render = (page) => {
            return new Promise((resolve, reject) => {
                const pageUrl = path.join(__dirname, `./views/${page}`);
                fs.readFile(pageUrl, "utf8", (err, data) => {
                    if (!err) {
                        resolve(data);
                    } else {
                        reject(err);
                    }
                });
            });
        };
        
        /**
         * 根据url获取渲染的HTML文件
         * @param {*} url 请求url
         */
        const route = async (url) => {
            let view;
            switch (url) {
                case "/":
                case "/index":
                    view = "index.html";
                    break;
                case "/users":
                    view = "users.html";
                    break;
                case "/todo":
                    view = "todo.html";
                    break;
                default:
                    view = "not-found.html";
                    break;
            }
            const html = await render(view);
            return html;
        };
        
        app.use(async (ctx) => {
            const url = ctx.request.url;
            const html = await route(url);
            ctx.body = html;
        });
        
        app.listen(3000, () => {
            console.log("The server running at: http://localhost:3000/");
        });
      • 其他文件源码参考

        <!-- index.html -->
        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <meta
                    name="viewport"
                    content="width=device-width, initial-scale=1.0"
                />
                <title>首页</title>
                <style>
                    .index {
                        display: flex;
                        justify-content: center;
                        align-items: center;
                    }
                </style>
            </head>
            <body>
                <div class="index">
                    <h1>首页</h1>
                    <ul>
                        <li><a href="/users">用户列表</a></li>
                        <li><a href="/todo">待办事项</a></li>
                    </ul>
                </div>
            </body>
        </html>
        <!-- users.html -->
        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <meta
                    name="viewport"
                    content="width=device-width, initial-scale=1.0"
                />
                <title>用户页列表</title>
                <style>
                    .users {
                        margin: 0 auto;
                        padding: 20px;
                    }
        
                    span {
                        margin-right: 50px;
                    }
        
                    span.title {
                        font-weight: bolder;
                    }
                </style>
            </head>
            <body>
                <div class="users">
                    <h1>用户列表</h1>
                    <p>
                        <span class="title">用户名</span>
                        <span class="title">年龄</span>
                        <span class="title">地址</span>
                    </p>
                    <hr />
                    <p>
                        <span>Divier</span>
                        <span>18</span>
                        <span>北京市海淀区中关村</span>
                    </p>
                    <p>
                        <span>陈皮皮</span>
                        <span>20</span>
                        <span>北京市昌平区回龙观</span>
                    </p>
                    <p>
                        <span>哈士奇</span>
                        <span>16</span>
                        <span>北京市朝阳区望京</span>
                    </p>
                </div>
            </body>
        </html>
        <!-- todo.html -->
        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <meta
                    name="viewport"
                    content="width=device-width, initial-scale=1.0"
                />
                <title>代办清单</title>
                <style>
                    .todo {
                        margin: 0 auto;
                    }
                </style>
            </head>
            <body>
                <div class="todo">
                    <h1>代办清单列表</h1>
                    <ul>
                        <li>学习Koa</li>
                        <li>洗衣做饭</li>
                        <li>跑步</li>
                    </ul>
                </div>
            </body>
        </html>
        <!-- not-found.html -->
        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <meta
                    name="viewport"
                    content="width=device-width, initial-scale=1.0"
                />
                <title>404</title>
                <style>
                    h1 {
                        text-align: center;
                    }
                </style>
            </head>
            <body>
                <h1>您访问的地址不存在!</h1>
            </body>
        </html>
      • 运行项目

        node index.js
      • 访问效果

  • Koa Router 路由系统

    Koa Router 是 Koa 的一个路由中间件, 项目地址

    koa-router 的特点:

    koa-router特点

    • koa-router 的安装和使用

      # 安装
      yarn add koa-router
      // 简单示例代码
      const Koa = require("koa");
      const Router = require("koa-router");
      
      const app = new Koa();
      const router = new Router();
      
      router.get("/", async (ctx, next) => {
          const result = {
              code: 2000,
              msg: "数据请求成功!",
              status: "SUCCESS",
              data: {
                  user: { name: "Diviner", age: 18, hobby: "Code & Share" },
              },
          };
          ctx.body = result;
      });
      
      // 使用 koa-router 中间件
      app.use(router.routes()).use(router.allowedMethods());
      
      app.listen(3000, () => {
          console.log("The server running at: http://localhost:3000/ ");
      });
    • 运行项目: node index.js, 打开浏览器,地址栏输入:http://localhost:3000/ 。 查看结果

      第一个koa-router程序运行结果

    • koa 常用请求方法示例

      // 主要代码
      
      router
          .get("/user/:id", (ctx, next) => {
              ctx.body = {
                  method: ctx.method,
                  url: ctx.url,
              };
          })
          .post("/user", (ctx, next) => {
              ctx.body = {
                  method: ctx.method,
                  url: ctx.url,
              };
          })
          .patch("/user/:id", (ctx, next) => {
              ctx.body = {
                  method: ctx.method,
                  url: ctx.url,
              };
          })
          .del("/user/:id", (ctx, next) => {
              ctx.body = {
                  method: ctx.method,
                  url: ctx.url,
              };
          });
    • router.alll() 方法

      此方法可以处理任意请求方式的请求, 比如上面的 四种方法

      router.all("/userInfo", (ctx, next) => {
          ctx.body = {
              method: ctx.method,
              url: ctx.url,
              ...result,
          };
      });

获取请求参数

  • 获取 GET 请求的参数
  • 获取 POST 请求的参数

  转载请注明:

文章作者: Diviner
文章链接: http://www.diviner.site/archives/b9cc6606.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Divinerの博客 !

评论
 上一篇
前端面试题整理之CSS篇 前端面试题整理之CSS篇
前端面试题整理之 CSS 篇此篇文章是对前端面试题 CSS 部分的整理,会不断进行更新 请使用 CSS 实现一个持续的动画效果 考察知识点 属性 描述 animation-name 规定需要绑定到选择器的 keyfra
下一篇 
Express入门指南 Express入门指南
Express 指南路由 编写中间件 使用中间件 使用模板引擎 错误处理 调试 Express 程序 数据库整合 路由 路由方法 路由方法是从 HTTP 方法之一派生出来的,并附加到了 Express 类的实例 以下是Express中
  目录