9

私はexpress.js / node.jsを学んでおり、javascriptプロトタイプモデルについて十分に理解していますが、十分ではありません。したがって、express.js のルーティング メカニズムでミドルウェアをスタックする方法について、少し混乱しています。

このコードがあるとしましょう

function andRestrictTo(role) {
    return function(req, res, next) {
       req.authenticatedUser.role == role
           ? next() : next(new Error('Unauthorized'));
   }
}

app.del('/user/:id', loadUser, andRestrictTo('admin'), function(req, res){
    res.send('Deleted user ' + req.user.name);
});

andRestrictTo(role) はミドルウェアを返すため、ルーティング チェーンで実行されます。でも:

  1. req、res、next パラメーターは、返された関数のどこから来ますか? 「チェーン」はどういうわけかそれをキューに入れ、パラメーターを割り当てていると思いますが、これは少しあいまいすぎて理解を深めることができません...

  2. 次のパラメーターとして発生するエラーで何が起こっていますか? エラーは単にミドルウェア チェーンを壊しますか?

  3. 制限メカニズムを別のファイル/モジュール (セキュリティ フレームワークなど) にパッケージ化したい場合、どのようにすればよいですか?

誰かが基本的なアイデアを指摘できればクールだろう:)

4

2 に答える 2

9

1)Express JSのソース、つまりNode.JSハンドラーから取得さreqれます(両方の変数は、実際にExpressのハンドラーに到達する前に少し変更されます)。その時点で、Expressはすべてのルートの配列を保持し、各ルートに、および関数を適用します。関数は、現在どのミドルウェアにあるかを認識しており(いくつかのスコープのトリックのため)、次のように呼び出します。次のハンドラーに移動します。reshttp.createServerreqresnextnextnext()

2)エラーが発生すると(実際には発生しませんが、渡されます)、関数はエラーハンドラーに移動します。エラーハンドラーは、たとえば(Expressドキュメントから取得)のメソッドをnext使用して定義できます。errorapp

app.error(function(err, req, res, next){
    if (err instanceof NotFound) {
        res.render('404.jade');
    } else {
        next(err);
    }
});

上げるerrorとミドルウェアのチェーンが壊れ、エラーハンドラーのチェーンに移動します(ご覧のとおり、エラーハンドラーでも使用nextします)。

3)まったく難しいことではありません:

security.js

module.exports = function(req, res, next) {
    console.log('Security middleware!');
    next();
}

app.js

app.get('/', require('./security'), ...);
于 2012-06-30T10:24:39.140 に答える
1

1) Express の (実際には Connect の) ルーティング コードは、HTTP リクエストを受け取り、それをすべてのミドルウェア関数に渡し始めます。リクエストに付随するreqandを使用してそれぞれを呼び出し、ルーティング コードの一部を呼び出すresa を追加します。nextチェーン内の次のミドルウェア関数に制御を渡します。

2) エラーは発生していません (throw実際にエラーを発生できるのはステートメントだけです)。Errorルーティング コードは、ミドルウェア関数がオブジェクトを返したことを認識し、それを適切に処理します。

3)それをエクスポートするモジュールに入れるだけですandRestrict(モジュール内で外部から使用できる唯一の関数である場合は、設定exports=andRestrictしてから呼び出しますrequire('mymodule'))。それ以外の場合は、2 つのステップで設定exports.andRestrict=<body of your function>して呼び出すことになります:mymodule=require('mymodule')初期とmymodule.andRestrict後で (たとえば、ミドルウェアとして渡す場合)。

于 2012-06-30T10:23:20.867 に答える