iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > html >如何使用nodejs中的koa
  • 333
分享到

如何使用nodejs中的koa

2024-04-02 19:04:59 333人浏览 薄情痞子
摘要

本篇内容主要讲解“如何使用nodejs中的koa”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用nodejs中的koa”吧!

本篇内容主要讲解“如何使用nodejs中的koa”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用nodejs中的koa”吧!

koa指的是一个类似于Express的基于Node实现的WEB框架,致力于成为web应用和api开发领域中的一个更小、更富有表现力、更健壮的基石。Koa并没有捆绑任何中间件,而是提供了一套优雅的方法,帮助用户快速而愉快地编写服务端应用程序。

如何使用nodejs中的koa

教程操作环境:windows7系统、nodejs 12.19.0&&koa2.0版、Dell G3电脑。

Koa是一个类似于Express的Web开发框架,创始人也是同一个人。它的主要特点是,使用了es6的Generator函数,进行了架构的重新设计。也就是说,Koa的原理和内部结构很像Express,但是语法和内部结构进行了升级。

Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。

官方faq有这样一个问题:”为什么koa不是Express 4.0?“,回答是这样的:”Koa与Express有很大差异,整个设计都是不同的,所以如果将Express 3.0按照这种写法升级到4.0,就意味着重写整个程序。所以,我们觉得创造一个新的库,是更合适的做法。“

1 Koa应用

一个Koa应用就是一个对象,包含了一个middleware数组,这个数组由一组Generator函数组成。这些函数负责对Http请求进行各种加工,比如生成缓存、指定代理、请求重定向等等。

var koa = require('koa');
var app = koa();

app.use(function *(){
  this.body = 'Hello World';
});

app.listen(3000);
  • 上面代码中,变量app就是一个Koa应用。它监听3000端口,返回一个内容为Hello World的网页。

  • app.use方法用于向middleware数组添加Generator函数

  • listen方法指定监听端口,并启动当前应用。
    它实际上等同于下面的代码。

var http = require('http');
var koa = require('koa');
var app = koa();
http.createServer(app.callback()).listen(3000);

2 中间件

Koa的中间件很像Express的中间件,也是对HTTP请求进行处理的函数,但是必须是一个Generator函数
而且,Koa的中间件是一个级联式(Cascading)的结构,也就是说,属于是层层调用,第一个中间件调用第二个中间件第二个调用第三个,以此类推。上游的中间件必须等到下游的中间件返回结果,才会继续执行,这点很像递归
中间件通过当前应用的use方法注册。

app.use(function* (next){
  var start = new Date; // (1)
  yield next;  // (2)
  var ms = new Date - start; // (3)
  console.log('%s %s - %s', this.method, this.url, ms); // (4)
});

上面代码中,app.use方法的参数就是中间件,它是一个Generator函数最大的特征就是function命令与参数之间,必须有一个星号。Generator函数的参数next,表示下一个中间件。
Generator函数内部使用yield命令,将程序的执行权转交给下一个中间件,即yield next,要等到下一个中间件返回结果,才会继续往下执行。

  • 上面代码中,Generator函数体内部,第一行赋值语句首先执行,开始计时,

  • 第二行yield语句将执行权交给下一个中间件,当前中间件就暂停执行

  • 等到后面的中间件全部执行完成,执行权就回到原来暂停的地方,继续往下执行,这时才会执行第三行,

  • 计算这个过程一共花了多少时间,第四行将这个时间打印出来。
    下面是一个两个中间件级联的例子。

app.use(function *() {
  this.body = "header\n";
  yield saveResults.call(this);
  this.body += "footer\n";
});

function *saveResults() {
  this.body += "Results Saved!\n";
}

上面代码中,第一个中间件调用第二个中间件saveResults,它们都向this.body写入内容。最后,this.body的输出如下。

header
Results Saved!
footer

只要有一个中间件缺少yield next语句,后面的中间件都不会执行,这一点要引起注意。

app.use(function *(next){
  console.log('>> one');
  yield next;
  console.log('<< one');
});

app.use(function *(next){
  console.log('>> two');
  this.body = 'two';
  console.log('<< two');
});

app.use(function *(next){
  console.log('>> three');
  yield next;
  console.log('<< three');
});

上面代码中,因为第二个中间件少了yield next语句,第三个中间件并不会执行。
如果想跳过一个中间件,可以直接在该中间件的第一行语句写上return yield next。

app.use(function* (next) {
  if (skip) return yield next;
})

由于Koa要求中间件唯一的参数就是next,导致如果要传入其他参数,必须另外写一个返回Generator函数的函数。

function logger(fORMat) {
  return function *(next){
    var str = format
      .replace(':method', this.method)
      .replace(':url', this.url);

    console.log(str);

    yield next;
  }
}
app.use(logger(':method :url'));

上面代码中,真正的中间件是logger函数的返回值,而logger函数是可以接受参数的。

3 多个中间件的合并

由于中间件的参数统一为next(意为下一个中间件),因此可以使用.call(this, next),将多个中间件进行合并。

function *random(next) {
  if ('/random' == this.path) {
    this.body = Math.floor(Math.random()*10);
  } else {
    yield next;
  }
};

function *backwards(next) {
  if ('/backwards' == this.path) {
    this.body = 'sdrawkcab';
  } else {
    yield next;
  }
}

function *pi(next) {
  if ('/pi' == this.path) {
    this.body = String(Math.PI);
  } else {
    yield next;
  }
}

function *all(next) {
  yield random.call(this, backwards.call(this, pi.call(this, next)));
}
app.use(all);

上面代码中,中间件all内部,就是依次调用random、backwards、pi,后一个中间件就是前一个中间件的参数。
Koa内部使用koa-compose模块,进行同样的操作,下面是它的源码

function compose(middleware){
  return function *(next){
    if (!next) next = noop();

    var i = middleware.length;

    while (i--) {
      next = middleware[i].call(this, next);
    }

    yield *next;
  }
}

function *noop(){}

上面代码中,middleware是中间件数组。前一个中间件的参数是后一个中间件,依次类推。如果最后一个中间件没有next参数,则传入一个空函数。

4 路由

可以通过this.path属性,判断用户请求的路径,从而起到路由作用。

app.use(function* (next) {
  if (this.path === '/') {
    this.body = 'we are at home!';
  }
})

// 等同于

app.use(function* (next) {
  if (this.path !== '/') return yield next;
  this.body = 'we are at home!';
})

下面是多路径的例子。

let koa = require('koa')

let app = koa()

// normal route
app.use(function* (next) {
  if (this.path !== '/') {
    return yield next
  }

  this.body = 'hello world'
});

// /404 route
app.use(function* (next) {
  if (this.path !== '/404') {
    return yield next;
  }

  this.body = 'page not found'
});

// /500 route
app.use(function* (next) {
  if (this.path !== '/500') {
    return yield next;
  }

  this.body = 'internal server error'
});

app.listen(8080)

上面代码中,每一个中间件负责一个路径,如果路径不符合,就传递给下一个中间件。
复杂的路由需要安装koa-router插件

var app = require('koa')();
var Router = require('koa-router');

var myRouter = new Router();

myRouter.get('/', function *(next) {
  this.response.body = 'Hello World!';
});

app.use(myRouter.routes());

app.listen(3000);

上面代码对根路径设置路由。
Koa-router实例提供一系列动词方法,即一种HTTP动词对应一种方法。典型的动词方法有以下五种。

  • router.get()

  • router.post()

  • router.put()

  • router.del()

  • router.patch()
    这些动词方法可以接受两个参数,第一个是路径模式,第二个是对应的控制器方法(中间件),定义用户请求该路径时服务器行为。

router.get('/', function *(next) {
  this.body = 'Hello World!';
});

上面代码中,router.get方法的第一个参数是根路径,第二个参数是对应的函数方法。
注意,路径匹配的时候,不会把查询字符串考虑在内。比如,/index?param=xyz匹配路径/index。
有些路径模式比较复杂,Koa-router允许为路径模式起别名。
起名时,别名要添加为动词方法的第一个参数,这时动词方法变成接受三个参数。

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

上面代码中,路径模式\users\:id的名字就是user。路径的名称,可以用来引用对应的具体路径,比如url方法可以根据路径名称,结合给定的参数,生成具体的路径。

router.url('user', 3);
// => "/users/3"

router.url('user', { id: 3 });
// => "/users/3"

上面代码中,user就是路径模式的名称,对应具体路径/users/:id。url方法的第二个参数3,表示给定id的值是3,因此最后生成的路径是/users/3。
Koa-router允许为路径统一添加前缀。

var router = new Router({
  prefix: '/users'
});

router.get('/', ...); // 等同于"/users"
router.get('/:id', ...); // 等同于"/users/:id"

路径的参数通过this.params属性获取,该属性返回一个对象,所有路径参数都是该对象的成员。

// 访问 /programming/how-to-node
router.get('/:cateGory/:title', function *(next) {
  console.log(this.params);
  // => { category: 'programming', title: 'how-to-node' }
});
param方法可以针对命名参数,设置验证条件。

router
  .get('/users/:user', function *(next) {
    this.body = this.user;
  })
  .param('user', function *(id, next) {
    var users = [ '0号用户', '1号用户', '2号用户'];
    this.user = users[id];
    if (!this.user) return this.status = 404;
    yield next;
  })

上面代码中,如果/users/:user的参数user对应的不是有效用户(比如访问/users/3),param方法注册的中间件会查到,就会返回404错误。
redirect方法会将某个路径的请求,重定向到另一个路径,并返回301状态码。

router.redirect('/login', 'sign-in');

// 等同于
router.all('/login', function *() {
  this.redirect('/sign-in');
  this.status = 301;
});

redirect方法的第一个参数是请求来源,第二个参数是目的地,两者都可以用路径模式的别名代替。

5 context对象

  • 中间件当中的this表示上下文对象context,代表一次HTTP请求和回应,即一次访问/回应的所有信息,都可以从上下文对象获得。

  • context对象封装了request和response对象,并且提供了一些辅助方法。每次HTTP请求,就会创建一个新的context对象。

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

context对象的很多方法,其实是定义在ctx.request对象或ctx.response对象上面
比如,ctx.typectx.length对应于ctx.response.typectx.response.length,ctx.path和ctx.method对应于ctx.request.path和ctx.request.method。
context对象的全局属性。

  • request:指向Request对象

  • response:指向Response对象

  • req:指向Node的request对象

  • req:指向Node的response对象

  • app:指向App对象

  • state:用于在中间件传递信息。

this.state.user = yield User.find(id);

上面代码中,user属性存放在this.state对象上面,可以被另一个中间件读取。
context对象的全局方法。

  • throw():抛出错误,直接决定了HTTP回应的状态码。

  • assert():如果一个表达式为false,则抛出一个错误。

this.throw(403);
this.throw('name required', 400);
this.throw('something exploded');

this.throw(400, 'name required');
// 等同于
var err = new Error('name required');
err.status = 400;
throw err;

6 错误处理机制

Koa提供内置的错误处理机制,任何中间件抛出的错误都会被捕捉到,引发向客户端返回一个500错误,而不会导致进程停止,因此也就不需要forever这样的模块重启进程。

app.use(function *() {
  throw new Error();
});

上面代码中,中间件内部抛出一个错误,并不会导致Koa应用挂掉。Koa内置的错误处理机制,会捕捉到这个错误。
当然,也可以额外部署自己的错误处理机制。

app.use(function *() {
  try {
    yield saveResults();
  } catch (err) {
    this.throw(400, '数据无效');
  }
});

上面代码自行部署了try...catch代码块,一旦产生错误,就用this.throw方法抛出。该方法可以将指定的状态码和错误信息,返回给客户端。
对于未捕获错误,可以设置error事件的监听函数。

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

error事件的监听函数还可以接受上下文对象,作为第二个参数。

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

如果一个错误没有被捕获,koa会向客户端返回一个500错误“Internal Server Error”。
this.throw方法用于向客户端抛出一个错误。

this.throw(403);
this.throw('name required', 400);
this.throw(400, 'name required');
this.throw('something exploded');

this.throw('name required', 400)
// 等同于
var err = new Error('name required');
err.status = 400;
throw err;
this.throw方法的两个参数,一个是错误码,另一个是报错信息。如果省略状态码,默认是500错误。

this.assert方法用于在中间件之中断言,用法类似于Node的assert模块。

this.assert(this.user, 401, 'User not found. Please login!');

上面代码中,如果this.user属性不存在,会抛出一个401错误。
由于中间件是层级式调用,所以可以把try { yield next }当成第一个中间件。

app.use(function *(next) {
  try {
    yield next;
  } catch (err) {
    this.status = err.status || 500;
    this.body = err.message;
    this.app.emit('error', err, this);
  }
});

app.use(function *(next) {
  throw new Error('some error');
})

7 cookie

cookie的读取和设置。

this.cookies.get('view');
this.cookies.set('view', n);

get和set方法都可以接受第三个参数,表示配置参数。其中的signed参数,用于指定cookie是否加密。
如果指定加密的话,必须用app.keys指定加密短语。

app.keys = ['secret1', 'secret2'];
this.cookies.set('name', '张三', { signed: true });

this.cookie的配置对象的属性如下。

  • signed:cookie是否加密。

  • expires:cookie何时过期

  • path:cookie的路径,默认是“/”。

  • domain:cookie的域名。

  • secure:cookie是否只有https请求下才发送。

  • httpOnly:是否只有服务器可以取到cookie,默认为true。

8 session

var session = require('koa-session');
var koa = require('koa');
var app = koa();
app.keys = ['some secret hurr'];
app.use(session(app));

app.use(function *(){
  var n = this.session.views || 0;
  this.session.views = ++n;
  this.body = n + ' views';
})

app.listen(3000);
console.log('listening on port 3000');

到此,相信大家对“如何使用nodejs中的koa”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 如何使用nodejs中的koa

本文链接: https://www.lsjlt.com/news/84782.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何使用nodejs中的koa
    本篇内容主要讲解“如何使用nodejs中的koa”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用nodejs中的koa”吧! ...
    99+
    2024-04-02
  • nodejs koa如何运行
    Node.js 是一个非常流行的 JavaScript 运行时环境,可用于构建各种类型的应用程序,包括服务器端应用程序。Koa 是一个轻量级的 Web 框架,基于 Node.js,它的出现是为了填补 Express 框架在某些方面的不足,通...
    99+
    2023-05-14
  • 如何使用koa-log4管理nodeJs日志
    小编给大家分享一下如何使用koa-log4管理nodeJs日志,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一.后端代码目录结构...
    99+
    2024-04-02
  • 如何解决使用nodejs+koa+typescript集成和自动重启的问题
    这篇文章主要为大家展示了“如何解决使用nodejs+koa+typescript集成和自动重启的问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何解决使用nodejs+koa+typescr...
    99+
    2023-06-22
  • nodejs里的koa-static中间件是什么
    这篇文章主要介绍“nodejs里的koa-static中间件是什么”,在日常操作中,相信很多人在nodejs里的koa-static中间件是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”nodejs里的k...
    99+
    2023-06-07
  • 使用nodejs + koa + typescript 集成和自动重启的问题
    目录版本说明创建项目安装依赖填充内容src/server.tstsconfig.jsonpackage.json运行参考资料版本说明 Node.js: 16.13.1 创建项目 创建...
    99+
    2024-04-02
  • nodejs中如何使用JWT
    这篇“nodejs中如何使用JWT”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“nodejs中如何使用JWT”文章吧。什么是...
    99+
    2023-07-04
  • 实用Nodejs npm包:koa-csrf的示例分析
    这篇文章将为大家详细讲解有关实用Nodejs npm包:koa-csrf的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。JS是什么JS是JavaScript的简称,它是一种直译式的脚本语言,其解释...
    99+
    2023-06-14
  • JWT如何在nodejs中使用
    这篇文章主要介绍“JWT如何在nodejs中使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JWT如何在nodejs中使用”文章能帮助大家解决问题。什么是JWTJ...
    99+
    2024-04-02
  • 如何在Nodejs中使用forEach
    如何在Nodejs中使用forEach?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。利用数组对象方法push/shift可实现队列先进先出特性,例如:>a=[][]>...
    99+
    2023-06-06
  • vue中如何引入koa
    在vue中引入koa的方法:1.新建vue.js项目;2.使用npm安装koa框架和中间件;3.使用require方法引入koa;具体步骤如下:首先,在vue-cli中创建一个vue.js项目;vue create project-name...
    99+
    2024-04-02
  • nodejs 如何使用
    Node.js 是一个运行在服务器端的 JavaScript 运行时环境,它能够解析和执行 JavaScript 代码。Node.js 很容易上手,因为 JavaScript 是世界上最流行的编程语言之一,并且 Node.js 有着庞大的社...
    99+
    2023-05-16
  • Node.js网络框架koa compose中间件如何使用
    这篇文章主要介绍了Node.js网络框架koa compose中间件如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Node.js网络框架koa compose中间件如何使用文章都会有...
    99+
    2023-07-04
  • Koa如何使用小技巧有哪些
    这篇文章将为大家详细讲解有关Koa如何使用小技巧有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。cookie的安全保护基于cookie来验证用户状态的系统中,如何提高...
    99+
    2024-04-02
  • nodejs中Express中间件如何使用
    本篇文章给大家分享的是有关nodejs中Express中间件如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Express是一个基于No...
    99+
    2024-04-02
  • Nodejs中express和ejs如何使用
    Nodejs中express和ejs如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。var express =&...
    99+
    2024-04-02
  • Nodejs中如何使用crypto模块
    本篇文章给大家分享的是有关Nodejs中如何使用crypto模块,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。crypto模块是nodejs的...
    99+
    2024-04-02
  • nodejs中superagent和cheerio如何使用
    这期内容当中小编将会给大家带来有关nodejs中superagent和cheerio如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。准备工作  使用npm管理依赖,...
    99+
    2024-04-02
  • nodejs如何使用debug
    Node.js作为一种非常流行的后端编程语言,广泛应用于开发各种Web应用、服务器、工具、框架和库等。但是,在开发过程中难免会出现各种各样的问题,例如代码错误、逻辑错误等等。这时候,一个好的调试工具是非常重要的。Node.js的调试工具被称...
    99+
    2023-05-14
  • 如何使用nodejs then
    本篇内容介绍了“如何使用nodejs then”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作