2

私はjavascriptが初めてで、node.jsに飛びつきました。私は多くの理論を読み、実用的な側面から始めました (私はモバイルアプリ用の API を書いています) が、ミドルウェアにつながる基本的な問題が 1 つあります。ミドルウェア機能を正常に実装しましたが、ミドルウェアのアイデアを使用して問題がないかどうかを知り、ミドルウェアに至った元の問題を解決したいと考えています。私の質問は2つあり、次のとおりです。

1)私が収集したものから、ミドルウェアを使用するというアイデアは、実際にリクエストを処理する前にプロセスを繰り返すことです。次のように、トークンの検証に使用しました: URL の 1 つだけがトークン パラメーターを受け取らないため、

app.js

app.get('/settings', auth.validateToken, auth.settings);

auth.js

function validateToken(req, res, next){ //code };

validateToken では、私のコードはトークンをチェックし、すべてが OK であれば next() を呼び出します。または、res を json として変更して特定のエラー コードを返します。
これに関する私の質問は次のとおりです。a) これはミドルウェアの正しい使用法ですか? b) 次の関数に値を渡す [正しい] 方法はありますか? すべてが OK の場合にのみ next を呼び出す代わりに、どちらの方法でも next を呼び出し、ミドルウェアが成功したかどうかを next 関数の内部から知る [正しい] 方法はありますか? ある場合、これはミドルウェアの適切な使用でしょうか? この正確なポイントは、関数をカプセル化するという最初の問題と、この質問のパート 2 につながります。

この部分は修正されました。私の 2 番目のコメントを参照してください。
2) 私は、validateToken を単純にカプセル化し、get ハンドラーが指す関数 (auth.settings など) 内から呼び出すことができるミドルウェアを発見しました。私は一般的なシーケンシャル プログラミングに慣れており、javascript ではなく、node.js のイベント ベースの性質を考慮して、これを行う方法を理解できませんでした。
私が今やりたいことは、ユーザーとパスワードを単純に検証する関数を書くことです。特定のハンドラー内に完全に記述しましたが、別のハンドラーにコピーして貼り付けようとしていたため、停止しました。ゼロから正しい方法で物事を行い、node.js を理解したいです。私が抱えている具体的な問題の 1 つは、ユーザーとパスワードが一致しない場合に返さなければならないエラー コードが親関数によって異なることです。そのため、コールバック関数に伝えるにはこの関数が必要です。 「ねえ、パスワードとユーザーが一致しません」なので、親関数から正しいメッセージで応答できます。
私が実際に望んでいるのは、別の関数内から呼び出すことができる非同期関数を作成することだと思います。

私は自分でこれを解決しようとしてきましたが、実際の問題が何であるかについて頭を悩ませることはできません。 jsJS. 前もって感謝します!ジェニファー。

4

2 に答える 2

2

1) res.locals オブジェクト ( http://expressjs.com/api.html#res.locals ) は、リクエストに対してローカルにデータを保存し、それらをあるミドルウェアから別のミドルウェアに渡すように設計されています。リクエストが処理された後、このオブジェクトは破棄されます。セッション内にデータを保存したい場合は、req.session を使用できます。

2) 私があなたの質問を理解した場合、呼び出し元に非同期で応答を渡す関数が必要です。ほとんどのノードの機能が設計されているのと同じ方法でそれを行うことができます。

次のように関数を定義します。

function doSomething(parameters, callback) {
    // ... do something

    // if (errorConddition()) err = errorCode();

    if (callback) callback(err, result)
}

呼び出し元は、関数の戻り値を使用する代わりに、コールバックをこの関数に渡します。

function caller(req, res, next) {
   //... 

   doSomething(params, function(err, result) {

       if (! err && result) {
           // do something with the result
           next();
       } else {
           // do something else

           next();

           // or even res.redirect('/error');
       }
   });

}

同様のコールバック関数を書いていることに気付いた場合は、それらを関数として定義し、関数をパラメーターとして渡す必要があります。

//...

doSomething(param, processIt);

function processIt(err, result) {
   // ...
}

おそらく、あなたを混乱させているのは、まだ関数を値として扱っていないことです。これは、JavaScript に非常に特有のものです (ほとんど使用されていない言語は考慮されていません)。

于 2013-03-16T17:08:45.163 に答える
1

validateToken では、私のコードはトークンをチェックし、すべてが OK であれば next() を呼び出します。または、res を json として変更して特定のエラー コードを返します。

a) これはミドルウェアの正しい使い方ですか? b) 次の関数に値を渡す [正しい] 方法はありますか?

はい、これはミドルウェアを使用する正しい方法ですが、応答メッセージのタイプと仕様によっては、接続の組み込みエラー処理を使用できます。つまり、この例では、 next({status:401,stack:'Unauthorized'}); を呼び出して 401 ステータス コードを生成しています。

ミドルウェア システムは、1 つの関数が要求に応答するまで一連の関数を実行することによって、要求を処理するように設計されています。これが、次の関数がエラーである引数を 1 つしかとらない理由です。

-> エラー オブジェクトが次の関数に渡された場合、それは応答の作成に使用され、それ以上のミドルウェアは処理されません。エラー応答の作成方法は次のとおりです。

    // default to 500
    if (res.statusCode < 400) res.statusCode = 500;
    debug('default %s', res.statusCode);

    // respect err.status
    if (err.status) res.statusCode = err.status;

    // production gets a basic error message
    var msg = 'production' == env
      ? http.STATUS_CODES[res.statusCode]
      : err.stack || err.toString();

-> ミドルウェア スタックに値を渡すには、リクエスト オブジェクトを変更するのが最善の方法です。これにより、すべての処理がその特定の要求にバインドされ、要求オブジェクトがすべてのミドルウェア関数を通過するため、情報をスタックに渡すのに適した方法になります。

于 2013-03-15T06:03:19.600 に答える