このチュートリアルのコード リポジトリにアクセスしてください:
https://github.com/chencl1986/koa2-tutorial
KoaとExpressの違い
Express はコールバック関数に基づいて開発されています。
KoaはPromiseの考えに基づいて開発されました。
Koa1 は Generator に基づいており、Koa2 は Generator と Async/await の両方をサポートしていますが、Koa3 は完全に Async/await に基づいているため、Generator を使用すると警告が表示されます。
Koa を使用してサーバーを作成する
const また = require('また')
const server = new Koa() // new を使用してサーバーを作成します
server.listen(8080) //ポート 8080
1
2
3
4
5をリッスンし
、Koa ルーティングを導入します
Server01.jsを確認してください。Koa
にはExpressとは異なりルーティング機能が搭載されていないため、ルーティング機能を利用するにはkoa-routerモジュールを導入する必要があります。
/**
* コードを参照してください: /server01.js
*/
const router = new Router()
// 一般的に使用されるルーター メソッドには、get (get リクエストの照合)、post (post リクエストの照合)、all (すべてのリクエストの照合) があります。
// ctx はコンテキスト オブジェクトであり、ネイティブ Nodejs に含まれるリクエスト/レスポンス オブジェクト (それぞれ ctx.req/ctx.res) が含まれます。
// 次の関数が呼び出されると、ミドルウェアは一時停止され、制御が次のミドルウェアに渡されます。
// getメソッドで要求されたルートを決定
router.get('/a', async (ctx, next) => { console.log(ctx) ctx.body = 'aaa' // データ ctxをフロントに送信body 属性を通じて.body += 'bbb' // body 属性の値は、通常のオブジェクトの属性と同様に追加または置換できます。 } )
server.use(router.routes()) // use メソッドを使用してルーターミドルウェアをサーバーに追加します。
1
2
3 4
5
6
7
8
9
10
11
12
13
14
15
16
17
18もちろん、プロジェクトでは複数レベルのルーティングが行われることが多く、このときネストされたルーティングを作成する必要があります
。
ネストされたルーティング
ルーティングのネストを通じてマルチレベルのルーティング アクセスを実現するには、server01.js を参照してください。
/**
* コードを参照してください: /server01.js
*/
// ネストされたルーティング
const router = new Router() // メイン ルートを作成します
const userRouter = new Router() // ルートを作成します
const companyRouter = new Router( )
companyRouter.get('/a', async (ctx, next) => { // ルートを照合した後、対応するコンテンツが出力されます
ctx.body = エンタープライズの 'a'
})
userRouter.use('/company', companyRouter.routes()) // company ルートを親に追加します。これは、/company のサブルートにアクセスするときに、company の下のルートが一致することを意味します。
userRouter.get('/', async (ctx, next) => { ctx.body = 'user' })
userRouter.get('/company', async (ctx, next) => { ctx.body = '企业' })
router.use('/user', userRouter.routes()) // userRouter をメインのルーティング ルーターに追加します。
1
2
3
4 5
6
7
8
9 10
11
12
13
14
15
16
17
18 19 20
21
22
23 24このとき、ブラウザが別のルートにアクセスすると、対応するコンテンツが表示されます。
アクセス パス 表示内容
/user user
/user/company Enterprise
/user/company/a Enterprise a
Koa がこのようなネスト方式を選択する理由は、主に大規模プロジェクトをサポートするためです。大規模なプロジェクトでは、JSON を使用してルーティングを構成すると、コードの量が多くなり、読みにくくなります。
もちろん、現在の設定方法を使用する場合、すべてのルートを 1 つのファイルに設定することはコードの読み取りには役に立たないため、ルーティングの各レベルを別のファイルに設定し、モジュールを相互に参照することでこれを実現する必要があります。構成。
ルーティングがネストされている場合、最終的にアクセスされるパスは各レベルのパスの文字列によって連結されるため、「//user」などの接続エラーを起こさないように注意する必要があります。
'' 空の文字列はルート ルートを表します
'' 文字列はすべてのルートの一致を表します
モジュール式のネストされたルーティング
まずはserver02.jsを確認し
、エントリーjsファイルにルートノードのサーバーへのルートを追加します。
server.use(require('./routers')) // ルートルートの設定を使用する
1.
ルートルートの設定では、下位ルートの設定などを参照します。
const Router = require('koa-router')
const router = new Router()
// このとき、require('./user') の正体はミドルウェアである router.routes() なので、router.use を使う必要があります router.use
('/user', require('./user' ))
router.get('/user', async (ctx, next) => { ctx.body = 'user' })
module.exports = router.routes()
1
2
3
4
5
6
7
8
9
10
11
12
これでプロジェクト全体のルーティング設定が完了しました。
ルーティングパラメータ
ルーティングを介したパラメーターの受け渡しをサポートする Koa のserver03.js を参照してください。
router.get('/news/:id', async (ctx, next) => { console.log(ctx.params) // params 属性を通じてパラメータ ctx.body を取得 = `ニュース ID は: ${ctx .params .id}` }) 1 2 3 4同時に、多段階のパラメータ転送も行うことができますが、このとき、受信パラメータの数とパラメータの数が同じ場合のみ注意してください。ルートを正しくマッチングできると同時に、パラメータの順序も固定されます。
router.get('/news/:id1/:id2/:id3', async (ctx, next) => { console.log(ctx.params) ctx.body = `マルチレベル ニュース ID は次のとおりです: ${ ctx.params.id1}/${ctx.params.id2}/${ctx.params.id3}` }) 1 2 3 4同じルートの 2 つのレイヤが同時に一致したと仮定すると、一致するルートはレベルルーティングは実行されません。
router.get('/news/:id') // このルートのマッチングのみが実行されます。
router.get('/news/1')
1
2
第 1 レベルのルートを照合した後、第 2 レベルのルートを照合したい場合は、next() を実行することでメソッドを次のレベルに渡すことができますが、このときnext()の戻り値はPromiseなのでawaitを使う必要があります。
// next が実行されない場合、ルートのみ
router.get('/news/1', async (ctx, next) => { console.log(ctx.params) // params 属性を通じて パラメータ ctx を取得します。 body = `ニュースIDは:固定1` await next() // next関数を使用して次のレベルのマッチングを実行できますが、同時にnext()の戻り値は現時点ではPromiseなので、 await を使用する必要があります。} )
router.get('/news/:id', async (ctx, next) => { console.log(ctx.params) // params 属性を通じてパラメータ ctx.body を取得 = `ニュース ID は: ${ctx .params .id}` await next() })
router.get('/news/:key', async (ctx, next) => { console.log(ctx.params) // params 属性を通じて パラメータ ctx.body を取得します= `ニュース ID は: ${ctx .params .key}` await next() }) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Urlencoded の受け渡しとルート パラメーターの受け渡しの違い
server03.js を確認してください
Urlencoded: http://localhost:8080/news/1/2/3/user/1/2/3
ルーティングパラメータ: http://localhost:8080/news?id1=1&id2=2&id3= 3
Urlencoded パラメータ転送 ルート パラメータ転送
ctx.query を通じてパラメータを取得 ctx.params を通じてパラメータを取得
柔軟な順序 固定順序
省略可能 動的アドレスは省略できません
、検索エンジンはそれが単なる 1 つのアドレスであると認識し、SEO に貢献しません 静的アドレス、検索エンジンは複数のアドレスとして判断するため、SEO
パラメータに有利です パラメータの後にルートをマウントすることはできません 下位レベルのルーティング
コンテキスト コンテキストはパラメータの後にマウントできます
server04 をご覧ください。js
コンテキストは ctx のプロトタイプであり、通常はグローバル プロパティまたはメソッドをプロジェクト全体に追加するために使用されます。
最も一般的な使用法は、グローバル データベース接続プールを追加することです。
サーバー.コンテキスト.db = db();
server.use(async ctx => { console.log(ctx.db); }); 1 2 3 4 5グローバル プロパティを追加して出力します。
サーバー.コンテキスト.a = 123
router.get('/', async (ctx, next) => { ctx.body = `abc${server.context.a}` }) 1 2 3 4 5 ctx.throw と ctx.assert
server05.js をご覧ください。
ctx.throw([status], [msg], [properties])
ctx.throw メソッドは、フロントエンドにエラーをスローするために使用されます。
router.get('/login', async (ctx, next) => { if (!ctx.query.user || !ctx.query.pass) { ctx.throw(400, 'ユーザー名またはパスワードが存在しません' ) } else { ctx.body = 'Success' } }) 1 2 3 4 5 6 7 ctx.assert(value, [status], [msg], [properties]) ctx.assert は単純に throw をカプセル化したものです。最初のパラメータはトリガー条件です。次のコードと同等です。
if (!value) { ctx.throw(code, msg) } 1 2 3したがって、前のスロー コードは次のように省略できます。
router.get('/login', async (ctx, next) => { ctx.assert(ctx.query.user, 400, 'ユーザー名が存在しません') ctx.assert(ctx.query.pass, 400, ' パスワードが存在しません') ctx.body = '成功' }) 1 2 3 4 5 ctx.redirect
リダイレクトについてはserver06.js
ctx.redirectを参照してください。サイト内外へのリダイレクトが可能であり、同時に302ステータスコードがフロントエンドに送信されます。
router.get('/google', async (ctx, next) => { ctx.redirect('https://www.google.com/') })
router.get('/login', async (ctx, next) => { ctx.redirect('/user') }) 1 2 3 4 5 6 7koa -static を使用して静的ファイルを処理する
「server07.js」を参照してください。
const Static = require('koa-static')
// ルーティング経由で静的ファイルを使用する場合、ルーティングが直接アクセスを受け入れることになるため、all メソッドを使用する必要があります。
server.use(Static('./static', { // ./static フォルダー内の静的ファイルを使用します
maxage: 86400 * 1000, // キャッシュ時間
インデックスをブラウザーに通知します: '1.html' // Huang Wengen ルーティングの際、ルートがルート ルートと一致しない限り、デフォルトでファイルがレンダリングされます })
)
1
2
3
4
5
6
7
ルーティングを使用して静的ファイルを処理する
プロジェクト開発における静的ファイルのバッチ処理については、server08.js を確認してください。ルーティングを使用してさまざまなファイル タイプに一致させ、koa-static を通じて処理し、さまざまなキャッシュ時間などのパラメーターを追加できます。
const staticRouter = new Router()
staticRouter.all(/(\.jpg|\.png|\.gif)/, Static('./static', { maxage: 60 * 86400 * 1000 }))
staticRouter.all(/(\.css)/, Static('./static', { maxage: 1 * 86400 * 1000 }))
staticRouter.all(/(\.html|\.htm|\.shtml)/, Static('./static', { maxage: 20 * 86400 * 1000 }))
staticRouter.all(/(\.js|\.jsx)/, Static('./static', { maxage: 1 * 86400 * 1000 }))
// '' 空の文字列はルート ルートを表します
// '*' 文字列 * はすべてのルートの一致を表します
staticRouter.all('*', Static('./static', { maxage: 30 * 86400 * 1000 }))
server.use(staticRouter.routes())
1
2
3 4
5
6
7
8
9
10
11
12
13
14 15 16 17 18 19 20 21 22 23 24 25
koa -better-body ミドルウェア
server09.js をご覧ください。
koa-better-body ミドルウェアは、データやファイルを含む投稿リクエストを解析するために使用されます。
https://github.com/tunnckoCoreLabs/koa-better-body
新しい post.html を作成して、フォームをアップロードします。
<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form action=" http://localhost:8080/upload" method="post" enctype="multipart/form-data">
名前:<input type="text" name="user" /><br>
画像:<input type= "file" name="f1" /><br>
<input type="submit" value="提交">
</form>
</body>
</html>