开始

就像官网上说的,一切框架都从一个"Hello World"开始,首先我们新建一个 package.json,内容尽量简单:

{
"name": "koa-note",
"description": "Koa 学习笔记",
"main": "index.js"
}

然后 npm 安装 Koa

npm i koa

将官网上给的示例粘贴进去:

const Koa = require('koa');
const app = new Koa(); app.use(ctx => {
ctx.body = 'Hello World';
}); app.listen(4000);

然后执行 node --harmony index.js,就可以在浏览器中访问 http://localhost:4000/ 了。

注1:ctx 是 context 的简写,下面详细介绍。

注2:示例源码

2个关键点

Koa 的核心设计思路是为中间件层提供高级语法糖封装,以增强其互用性和健壮性,并使得编写中间件变得相当有趣。Koa 应用是一个包含一系列中间件 generator 函数的对象。

中间件级联

Koa 通过 generators 来实现“真正”的中间件。 Connect 简单地将控制权交给一系列函数来处理,直到函数返回。 与之不同,当执行到 yield next 语句时,Koa 暂停了该中间件,继续执行下一个符合请求的中间件('downstrem'),然后控制权再逐级返回给上层中间件('upstream')。

    const Koa = require('koa');
const app = new Koa(); // 定制请求头
app.use(async function (ctx, next) {
const start = new Date();
await next();
const ms = new Date() - start;
ctx.set('X-Response-Time', `${ms}ms`);
}); // 日志
app.use(async function (ctx, next) {
const start = new Date();
await next();
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}`);
}); // 请求内容
app.use(ctx => {
ctx.body = 'Hello World';
});

上面的例子在页面中返回 "Hello World",然而当请求开始时,请求先经过定制请求头和日志中间件,并记录中间件执行起始时间。 然后将控制权交给 reponse 中间件。当中间件运行到 yield next 时,函数挂起并将控制前交给下一个中间件。当没有中间件执行 yield next 时,程序栈会逆序唤起被挂起的中间件来执行接下来的代码。

为了方便理解我 YY 了下面的例子:

// 定制请求头
app.use(async function (ctx, next) {
console.log('step 1');
await next();
console.log('step 5');
}); // 日志输出
app.use(async function (ctx, next) {
console.log('step 2');
await next();
console.log('step 4:');
}); // 请求内容
app.use(ctx => {
console.log('step 3');
});

注:示例源码

说到中间件就不得不提到中间件的开发,简单地说中间件就是一个回调函数,中间件的原理可以参考下面这个"洋葱模型":

2.x 版可以使用 yield 来分割 request 和 response,但是 2.0 发版后就明确说明在 3.x 希望使用 await 来代替 yield,也就是要从 generator function 升级到 async function。某些组件还没有进行升级,经常会看到控制台上又这样的警告信息 "Support for generators will be removed in v3.",其中常用的 koa-router 和 koa-proxy 就在其中,如果想去除警告,并且与下一个版本兼容,可以参考 koa-static 这个库(做静态文件路由的一个中间件)。

app 的几个方法

app.listen(),为应用绑定端口,参数的详细文档请查看nodejs.org

app.callback(),返回一个适合 http.createServer() 方法的回调函数用来处理请求。

app.use(function),为应用添加指定的中间件,详情请看 Middleware

app.keys=,设置签名Cookie密钥。

app.context,方便扩展 ctx:

app.context.db = db();

app.use(async (ctx) => {
console.log(ctx.db);
});

app.on,典型的是错误处理:

app.on('error', function(err){
log.error('server error', err);
});

上下文

Koa Context 将 node 的 request 和 response 对象封装在一个单独的对象里面,其为编写 web 应用和 API 提供了很多有用的方法。

app.use(function *(){
this; // is the Context
this.request; // is a koa Request
this.response; // is a koa Response
});

一堆 API 就不写了,自行到官网查看。

中间件

Koa 就是一个框架,大部分功能还需要靠中间件实现。

中间件 koa-router

安装

npm install koa-router

使用

const Koa = require('koa');
const app = new Koa();
const router = require('koa-router')(); router.get('/', function *(next) {
this.body = 'Hello World!';
}); router.get('/a', function *(next) {
this.body = 'Hello World A!';
}); app.use(router.routes());
app.listen(4000); console.log('服务已启动: localhost:4000');

RESTFul 风格的路由像这样配置:

router.get('/users/:id', function *(next) {
// ...
}).del('/users/:id', function *(next) {
// ...
});

官网:koa-router

中间件 koa-static

安装

npm i koa-static --save

使用

const koaStatic = require('koa-static')('./');
app.use(koaStatic);

说明:

  • 第一个参数指定根路径
  • 第二个参数指定各种配置项

注意:

默认请求指向 index.html 文件,当然你可以通过第二个参数 options 自定义默认请求的文件。如果配置了 koa-router 的默认路径那么静态文件的路由默认会失效。如下面访问 http://localhost:4000/ 这样的路径会返回报 404,而不会去读取 ../dist/index.html 文件并返回。

router.get('/', function *(next) {
});
const koaStatic = require('koa-static')('./', {
index: '../dist/index.html'
});

其他参数参考 koa-static 中间件官网:koa-static

注:示例源码,示例验证了 HTML,图片,CSS 和 JS 静态文件的加载。

中间件 koa-proxy

安装

npm i koa-proxy --save

代理接口,默认只代理接口不代理静态文件,当前的 router 优先,也就是说如果已经配置了某接口的路由,那么此接口不会被代理带其他服务器上。

const koaProxy = require('koa-proxy')({
host: 'http://127.0.0.1:5000'
});
app.use(koaProxy);

也可以给静态文件做远程代理:

app.get('index.js', proxy({
url: 'http://127.0.0.1:5000/index.js'
}));

注1:示例源码。 注2:中间件 koa-proxy

意外收获的包

读源码的时候发现了很多服务器开发有用的包,下面列一下:

co

Generator 函数执行器,TJ大神的作品。GitHub

co(gen);

methods

Node 支持的 http 类型,这种只返回一个数组的小包居然也是 TJ 大神创立的。GitHub

assert

对 Node 原生包的扩展,支持浏览器。GitHub

// 判空
assert(root, 'root directory is required to serve files');

http-errors

处理 http 异常的模块,这个做服务器端开发肯定少不了。GitHub

cookie

这种包用途也很广泛。GitHub

path-to-regexp

非常棒的路径匹配和 RESTFul 地址转化的工具。GitHub

is-generator-function

判断一个函数是否是 Generator 函数。GitHub

const isG = require('is-generator-function');
isG(fn);

 

Koa 学习笔记的更多相关文章

  1. koa学习笔记

    卸载node http://www.it165.net/os/html/201504/12427.html 安装 sudo npm install -g n sudo n stable 装个稳定版试试 ...

  2. Node、TS、Koa学习笔记

    这样定义可以轻松拿到gender属性 这样定义,函数内显示没有gender 这种方法能得到gender但是函数内部没有gender 这种方式能到gender 但是在函数里施symbel属性,外部不能访 ...

  3. Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...

  4. [转]Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    本文转自:https://www.cnblogs.com/zhongweiv/p/nodejs_koa2_webapp.html 目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装 ...

  5. Nodejs学习笔记(十五)—Node.js + Koa2 构建网站简单示例

    前言 前面一有写到一篇Node.js+Express构建网站简单示例:http://www.cnblogs.com/zhongweiv/p/nodejs_express_webapp.html 这篇还 ...

  6. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  7. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  8. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  9. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

随机推荐

  1. 桥接模式和nat模式的区别

    桥接模式:VMware虚拟的系统就想局域网中独立的主机一样(有独立的IP)它可以访问网内任何一台机器 Nat模式:可以通过宿主机访问互联网(宿主机联网,虚拟机就能联网)它不能和本局域网中的其他主机进行 ...

  2. 机器学习--Lasso回归和岭回归

    之前我们介绍了多元线性回归的原理, 又通过一个案例对多元线性回归模型进一步了解, 其中谈到自变量之间存在高度相关, 容易产生多重共线性问题, 对于多重共线性问题的解决方法有: 删除自变量, 改变数据形 ...

  3. iOS相关的ARM汇编

    一.iOS汇编1.真机:arm64汇编寄存器指令 堆栈2.模拟器:x86汇编 二.lldb (lldb)register read x0 (lldb)register read w0 (lldb)re ...

  4. 手工脱壳之AsPack压缩脱壳-随机基址

    一.工具及壳介绍二.脱壳1.ESP定律脱壳2.单步跟踪脱壳3.基址重定位的修复 一.工具及壳介绍 使用工具:Ollydbg.PEID.ImportREC.LoadPE.010 Editor 查看待脱壳 ...

  5. java 将指定文件夹递归的进行zip打包压缩

    package tmp.MavenTest; import java.io.BufferedInputStream; import java.io.File; import java.io.FileI ...

  6. handsontable 常用 配置项 笔记

    import React, { Component } from 'react'; import HotTable from 'react-handsontable'; import Handsont ...

  7. oracle自带总页数分页sql

    string strSQL = string.Format(@"select * from( with temp as (select * from * where {0} order by ...

  8. 解决Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules

    1.在eclipse的workspace里面找到该项目.settings文件夹 2.编辑org.eclipse.wst.common.project.facet.core.xml文件 <?xml ...

  9. UI交互设计关键词:情感化设计与心理

    情感化设计,一定有一个关键词.情感,是指人对周围事物和自身以及对自己行为的态度,它是人对客观事物的一种特殊的反映形式,是主体对外界刺激给予肯定或否定的心理反应,也是对客观事物是否符合自己需要的态度或体 ...

  10. Android学习(四)

    教材学习内容总结 图形和定制视图 硬件加速 Android APILevel14及其以上版本为目标的应用程序来说,硬件加速是默认可用的. 可通过android:hardwareAccelerated= ...