Nodejsのkoaとは何ですか
koa は、Express と同様の Node ベースの Web フレームワークを指し、Web アプリケーションおよび API 開発の分野において、より小さく、より表現力豊かで、より堅牢な基盤となるよう取り組んでいます。 Koa はミドルウェアをバンドルしていませんが、ユーザーがサーバー側アプリケーションを迅速かつ楽しく作成できるようにするための一連のエレガントなメソッドを提供します。
このチュートリアルの動作環境: Windows7 システム、nodejs バージョン 12.19.0&&koa2.0、Dell G3 コンピューター。
Koa
は Express に似た Web
開発フレームワークであり、創設者は同じ人です。最大の特徴は、ES6 Generator機能
を利用し、アーキテクチャを再設計したことです。つまり、Koa の原理と内部構造は Express と非常に似ていますが、構文と内部構造はアップグレードされています。
Koa は、Express の背後にいる人々によって構築された新しい Web フレームワークであり、Web アプリケーションと API 開発のより小さく、より表現力豊かで、より堅牢な基盤となるよう取り組んでいます。 Koa は、非同期関数を利用することにより、コールバック関数を破棄し、エラー処理を大幅に強化するのに役立ちます。 Koa にはミドルウェアはバンドルされていませんが、サーバー側アプリケーションを迅速かつ快適に作成できるようにする一連のエレガントなメソッドが提供されています。
公式faq
「なぜkoaはExpress 4.0ではないのですか?」という質問がありますが、その答えは次のとおりです: 「KoaはExpressとは大きく異なり、全体の設計は次のとおりです。」したがって、この方法で Express 3.0 を 4.0 にアップグレードすると、プログラム全体を書き直すことになります。そのため、新しいライブラリを作成する方が適切なアプローチであると考えています。"
1 Koa application
A Koa application
は、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
というコンテンツを含む Web ページを返します。 app.use
メソッドは、Generator 関数
をmiddleware
配列に追加するために使用されます。listen
メソッドは、リスニング ポートを指定し、現在のアプリケーションを起動します。
これは実際には以下のコードと同等です。
var http = require('http'); var koa = require('koa'); var app = koa(); http.createServer(app.callback()).listen(3000);
2 ミドルウェア
Koa
のミドルウェアは、Express のミドルウェア
とよく似ており、Express のミドルウェア
も HTTP リクエストを処理します。関数 を処理しますが、
Generator 関数
である必要があります。 さらに、Koa のミドルウェアは
Cascading 構造です。つまり、レイヤーごとに呼び出されます。
最初のミドルウェアが 2 番目のミドルウェア を呼び出し、2 番目のミドルウェアが
を呼び出します。 3 番目の など。
上流のミドルウェアは、実行を続行する前に、下流のミドルウェアが結果を返すまで待機する必要があります
これは再帰と非常によく似ています。 ミドルウェアは、現在のアプリケーションの
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) に移譲します。次のミドルウェアまで待つ必要があります。結果が返された場合にのみ実行が続行されます。 上記のコードでは、
ジェネレーター関数本体 内で、代入ステートメントの最初の行が最初に実行され、タイミングが開始されます。2行目
yield このステートメントは次のミドルウェアに実行権を渡し、現在のミドルウェアは実行を一時停止します。 後続のすべてのミドルウェアが実行されると、実行権は元の場所に戻ります。元々一時停止されていたため、実行は続行されます。3 行目は実行されます。
このプロセスにかかった時間を計算すると、今度は 4 行目が出力されます。 以下は 2 つのミドルウェア カスケードの例です。
app.use(function *() { this.body = "header\n"; yield saveResults.call(this); this.body += "footer\n"; }); function *saveResults() { this.body += "Results Saved!\n"; }
header Results Saved! footer
1 つのミドルウェアに
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'); });
上記のコードでは、2 番目のミドルウェアに
yield nextステートメントが欠落しているため、3 番目のミドルウェアは実行されません。 ミドルウェアをスキップしたい場合は、ミドルウェアの最初の行に 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'));
上記のコードでは、実際のミドルウェアはロガー関数の戻り値であり、ロガー関数はパラメーターを受け取ることができます。
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.type
和ctx.length
对应于ctx.response.type
和ctx.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 教程》】
以上がNodejsのkoaとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

Node.js と Tomcat の主な違いは次のとおりです。 ランタイム: Node.js は JavaScript ランタイムに基づいていますが、Tomcat は Java サーブレット コンテナです。 I/O モデル: Node.js は非同期ノンブロッキング モデルを使用しますが、Tomcat は同期ブロッキング モデルです。同時実行処理: Node.js はイベント ループを通じて同時実行を処理しますが、Tomcat はスレッド プールを使用します。アプリケーション シナリオ: Node.js はリアルタイム、データ集約型、同時実行性の高いアプリケーションに適しており、Tomcat は従来の Java Web アプリケーションに適しています。

Node.js はサーバー側の JavaScript ランタイムであり、Vue.js は対話型ユーザー インターフェイスを作成するためのクライアント側の JavaScript フレームワークです。 Node.js はバックエンド サービス API 開発やデータ処理などのサーバー側開発に使用され、Vue.js はシングルページ アプリケーションや応答性の高いユーザー インターフェイスなどのクライアント側開発に使用されます。

Node.js は、高いパフォーマンス、スケーラビリティ、クロスプラットフォーム サポート、豊富なエコシステム、開発の容易さなどの機能を備えているため、バックエンド フレームワークとして使用できます。

MySQL データベースに接続するには、次の手順に従う必要があります。 mysql2 ドライバーをインストールします。 mysql2.createConnection() を使用して、ホスト アドレス、ポート、ユーザー名、パスワード、データベース名を含む接続オブジェクトを作成します。 connection.query() を使用してクエリを実行します。最後に connection.end() を使用して接続を終了します。

Node.js インストール ディレクトリには、npm と npm.cmd という 2 つの npm 関連ファイルがあります。違いは次のとおりです。拡張子が異なります。npm は実行可能ファイルで、npm.cmd はコマンド ウィンドウのショートカットです。 Windows ユーザー: npm.cmd はコマンド プロンプトから使用できますが、npm はコマンド ラインからのみ実行できます。互換性: npm.cmd は Windows システムに固有ですが、npm はクロスプラットフォームで使用できます。使用上の推奨事項: Windows ユーザーは npm.cmd を使用し、他のオペレーティング システムは npm を使用します。

はい、Node.js はバックエンド開発言語です。これは、サーバー側のビジネス ロジックの処理、データベース接続の管理、API の提供などのバックエンド開発に使用されます。

Node.js には次のグローバル変数が存在します。 グローバル オブジェクト: グローバル コア モジュール: プロセス、コンソール、require ランタイム環境変数: __dirname、__filename、__line、__column 定数: unknown、null、NaN、Infinity、-Infinity

Node.js と Java の主な違いは、設計と機能です。 イベント駆動型とスレッド駆動型: Node.js はイベント駆動型で、Java はスレッド駆動型です。シングルスレッドとマルチスレッド: Node.js はシングルスレッドのイベント ループを使用し、Java はマルチスレッド アーキテクチャを使用します。ランタイム環境: Node.js は V8 JavaScript エンジン上で実行され、Java は JVM 上で実行されます。構文: Node.js は JavaScript 構文を使用し、Java は Java 構文を使用します。目的: Node.js は I/O 集中型のタスクに適しており、Java は大規模なエンタープライズ アプリケーションに適しています。
