Node.jsミドルウェアの仕組みの詳細な説明

Node.jsミドルウェアの仕組みの詳細な説明

Express ミドルウェアとは何ですか?

  • ミドルウェアとは、文字通り、ソフトウェアの 1 つの層と別の層の間に配置するものを意味します。
  • Express ミドルウェアは、Express サーバーへのリクエストのライフサイクル中に実行される関数です。
  • 各ミドルウェアは、接続されているすべてのルートの HTTP リクエストと応答にアクセスできます。
  • さらに、ミドルウェアは HTTP リクエストを終了したり、 next を使用して別のミドルウェア関数に渡したりすることもできます。このミドルウェアの「連鎖」により、コードを区分化し、再利用可能なミドルウェアを作成できます。

Expressミドルウェアを作成するための要件

Express ミドルウェアを作成、使用、テストするには、いくつかのものをインストールする必要があります。まず、Node と npm が必要です。インストールされていることを確認するには、次を実行します。

npm -v && ノード -v

インストールされている Node と NPM のバージョンが表示されます。エラーが発生した場合は、Node をインストールする必要があります。すべての例は、Node バージョン 8 以降および NPM バージョン 5 以降で使用する必要があります。

この記事では Express バージョン 4.x を使用します。バージョン 3.x からバージョン 4.x への重大な変更があるため、これは重要です。

Express ミドルウェア: 基礎

まず、Express の最も基本的な組み込みミドルウェアを使用します。新しいプロジェクトを作成し、npm で初期化します...

npm 初期化
npm インストールエクスプレス --save

server.js を作成し、次のコードを貼り付けます。

定数 express = require('express');
express() は、定数です。

app.get('/', (req, res, next) => {
  res.send('ようこそお帰りなさい');
});

アプリをリッスンする(3000);

ミドルウェアはどのような問題を解決しますか?なぜそれを使うのですか?

Web サーバー上で Node.js と Express を使用して Web アプリケーションを実行していると仮定します。このアプリでは、一部のページでログインする必要があります。

Web サーバーがデータの要求を受信すると、Express はユーザーとユーザーが要求しているデータに関する情報を含む要求オブジェクトを提供します。 Express では、応答オブジェクトへのアクセスも提供され、Web サーバーがユーザーに応答する前にこれを変更できます。これらのオブジェクトは、多くの場合、req、res と短縮されます。

ミドルウェア関数は、関連する情報を使用して req オブジェクトと res オブジェクトを変更するのに最適な場所です。たとえば、ユーザーがログインすると、データベースからユーザーの詳細を取得し、その詳細を res.user に保存できます。

ミドルウェアの機能はどのようになっているのでしょうか?

非同期関数userMiddleware(req, res, next) {
    試す {
        const userData = await getUserData(req.params.id); // 下記の app.get を参照

        if(ユーザーデータ) {
                要求ユーザー = ユーザーデータ;
                次();
        }
    } キャッチ(エラー) {
        res.status(500).send(error.message); //適切なエラー処理に置き換える
    }
}

エラーが発生し、他のコードを実行したくない場合は、関数を呼び出さないでください。この場合は必ず応答を送信してください。そうしないと、クライアントはタイムアウトするまで応答を待機します。

var app = express();

//通常のルートハンドラ
app.get('/user/:id', userMiddleware, userController);

ミドルウェアチェーン

ミドルウェア配列内でミドルウェアを連鎖したり、複数の app.use 呼び出しを使用したりすることができます。

app.use(ミドルウェアA);
app.use(ミドルウェアB);
app.get('/', [ミドルウェアC, ミドルウェアD], ハンドラー);

Express がリクエストを受信すると、終了アクションが発生するまで、リクエストに一致する各ミドルウェアが初期化された順序で実行されます。

したがって、エラーが発生すると、エラーを処理するためのすべてのミドルウェアが、そのうちの 1 つが next() 関数呼び出しを呼び出さなくなるまで順番に呼び出されます。

Expressミドルウェアの種類

  • router.use などのルーターレベルのミドルウェア
  • 組み込みミドルウェア: express.static、express.json、express.urlencoded
  • エラー処理ミドルウェア、例: app.use(err, req, res, next)
  • bodyparser、cookieparserなどのサードパーティミドルウェア
  • ルーターレベルのミドルウェア
  • express.Router モジュール式のインストール可能なルーティング ハンドラーを作成するには、express.Router クラスを使用します。ルーター インスタンスは、完全なミドルウェアおよびルーティング システムです。 ログ記録や認証などにミドルウェアを使用できます。以下に示すように、ユーザーの最新のアクティビティを記録し、認証ヘッダーを解析し、それを使用して現在ログインしているユーザーを特定し、それを Request オブジェクトに追加します。この関数は、プログラムが要求を受信するたびに実行されます。エラーが発生した場合は、後続のミドルウェアやルート処理を呼び出さずに、応答を終了します。
var ルーター = express.Router()
router.use() および router.METHOD() 関数を使用して、ルーター レベルのミドルウェアを読み込みます。
次の例では、ルーターをモジュールとして作成し、その中にミドルウェア関数をロードし、いくつかのルートを定義し、メイン アプリ内のパスにルーター モジュールをマウントします。
var express = require('express');
var ルーター = express.Router();

// マウントパスのないミドルウェア関数。このコードはルータへのリクエストごとに実行されます
// ログ記録
非同期関数 logMiddleware (req, res, next) {
    試す {
         console.log(req.user.id、新しい日付());
     次();
    } キャッチ() {
        res.status(500).send(エラーメッセージ);
    }
}
// 認証
    非同期関数 checkAuthentication(req, res, next) => {
// トークンのヘッダーまたは URL パラメータまたは POST パラメータをチェックします
const トークン = req.body.token || req.query.token || req.headers['x-access-token'] || req.headers['authorization'];
      if (トークン) {
        試す {
            // 秘密を検証する
            req.decoded = jwt.verify(token, config.secret) を待機します

            checkUser = authenticateTokenHelper.getUserDetail(req); を待機します。

            // 問題がなければ、他のルートで使用するために保存します
                if (checkUser) {
                        req.user = req.decoded
                        次()
                } それ以外 {
                    res.status(403).json({ を返します。 
                    メッセージ: responseMessage.noAuthorized 
                    })
                }
        } キャッチ (エラー) {
            res.status(401).json({ メッセージ: responseMessage.invalidToken }) を返します
        }
  } それ以外 {
    // トークンがない場合
    res.status(400).json({ メッセージ: responseMessage.invalidRequest }) を返します
  }
}
ルーターのログミドルウェアを使用します。
    router.get('/user, checkAuthentication, ハンドラ);

組み込みミドルウェア

Express には、次のミドルウェア関数が組み込まれています。

  • express.static は、HTML ファイル、画像などの静的リソースを提供します。
  • express.json ペイロードは、受信したリクエストを JSON で解析します。
  • express.urlencoded は、URL エンコードされたペイロードを含む受信リクエストを解析します。

エラー処理ミドルウェア

エラー処理ミドルウェアは常に 4 つの引数 (err、req、res、next) を取ります。 4 つの引数を指定して、これをエラー処理ミドルウェア関数として識別する必要があります。次のオブジェクトを使用する必要がない場合でも、それを指定する必要があります。そうしないと、次のオブジェクトは通常のミドルウェアとして解釈され、エラーを処理できなくなります。基本的な署名は次のとおりです。

app.use(関数 (err, req, res, next) {
  コンソールエラー(err.stack)
  res.status(500).send('問題が発生しました!')
})

例1:

app.get('/users', (req, res, next) => {
  next(new Error('エラーを渡しています!'));
});
app.use((err, req, res, next) => {
  コンソールログ(エラー);    
  if(!res.headersSent){
    res.status(500).send(err.message);
  }
});

この場合、パイプラインの最後にあるエラー処理ミドルウェアがエラーを処理します。また、res.headersSent プロパティをチェックしたことにも気付くかもしれません。これは、応答のヘッダーがすでにクライアントに送信されているかどうかを確認するだけです。そうでない場合は、HTTP 500 ステータスとエラー メッセージをクライアントに送信します。

例2:

エラー処理ミドルウェアを連鎖させることもできます。通常、エラーの種類によって処理方法が異なります。

app.get('/users, (req, res, next) => {
  let err = new Error('見つかりませんでした。');
  エラー httpステータスコード = 404;
  次へ(エラー);
});

app.get('/user, (req, res, next) => {
  let err = new Error('申し訳ありませんが、それはできません、Dave。');
  エラー.httpステータスコード = 304;
  次へ(エラー);
});

app.use((err, req, res, next) => {
   // 見つからないエラーを処理する
  (エラーhttpステータスコード === 404)の場合{
    res.status(400).render('見つかりません');
  }
   // 不正なエラーを処理する 
  そうでない場合(err.httpStatusCode === 304){
    res.status(304).render('権限がありません');
  }
    // すべてをキャッチ
   そうでない場合 (!res.headersSent) {
     res.status(err.httpStatusCode || 500).render('UnknownError');
  }
  次へ(エラー);
});
  • この場合、ミドルウェアは 404 (見つかりません) エラーがスローされたかどうかを確認します。そうである場合は、「NotFound」テンプレート ページをレンダリングし、ミドルウェア内の次の項目にエラーを渡します。
  • 次のミドルウェアは、304 (不正) エラーがスローされたかどうかを確認します。そうである場合は、「Unauthorized」ページをレンダリングし、パイプラインの次のミドルウェアにエラーを渡します。
  • 最後に、「catch all」エラー処理は単にエラーをログに記録し、応答が送信されない場合、間違った httpStatusCode (または何も提供されていない場合は HTTP 500 ステータス) を送信し、「UnknownError」テンプレートをレンダリングします。

サードパーティミドルウェア

場合によっては、バックエンドに追加機能を追加することもあります。必要な機能を取得するには Node.js モジュールをインストールし、アプリケーション レベルまたはルーター レベルでアプリケーションにロードします。

例: body-parser が Content-Type リクエスト ヘッダーを処理すると、すべてのミドルウェアは解析された本文を req.body プロパティに入力します。

定数 express = require('express');
bodyParser は、'body-parser' を必要とします。
express() は、定数です。
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json())
app.post('/save',(req,res)=>{
    res.json({
        "ステータス":true,
         「ペイロード」:req.body
    })
}
app.listen(3000,(要求,res)=>{
    console.log('ポートでサーバーが実行中')
})

要約する

ミドルウェア関数は、すべてのリクエストまたは特定のルートのすべてのリクエストでコードを実行し、リクエストまたは応答データに対してアクションを実行するのに最適な方法です。ミドルウェアは現代の Web サーバーの重要な部分であり、非常に便利です。

上記は、Node.js ミドルウェアの仕組みについての詳しい説明です。Node.js ミドルウェアの詳細については、123WORDPRESS.COM の他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • Nodejs の Express でよく使われるミドルウェア body-parser の解析
  • Node.js の Express ミドルウェアの詳細な理解
  • Node.js で画像を処理するミドルウェア、node-images の詳細な説明
  • Nodejs 開発 - 高速ルーティングとミドルウェア
  • NodeJS 学習ノート: Connect ミドルウェア アプリケーションの例
  • NodeJS 学習ノート: ミドルウェア モジュールの接続 (パート 2)
  • NodeJS 学習ノート: ミドルウェア モジュールの接続 (I)
  • Nodejs はブラックリストミドルウェア設計を実装します
  • node.js ミドルウェア express-session の使い方の詳しい説明

<<:  MySQL で datetime 型のデフォルト値を設定する方法

>>:  プライベートDockerリポジトリであるHarborをインストールするための詳細な手順

推薦する

Nginx における 2 つの現在の制限方法についての簡単な説明

負荷は通常、システム設計時に予測されます。システムがパブリック ネットワークに公開されている場合、悪...

スクロールバーのスタイルを設定するための CSS サンプルコード

スクロール バーのスタイルを設定するための CSS 実装コードは次のとおりです。 •::-webki...

ミニマルなウェブサイトデザインの例

Web アプリケーション クラス1. みんなのためにダウンまたは私だけのためにこのウェブサイトは、ウ...

Ubuntu 20.04 に GitLab をインストールして設定する方法

導入GitLab CE または Community Edition は、主に Git リポジトリのホ...

シェルスクリプトによるDockerコンテナの起動順序の制御の詳細な説明

1. 遭遇した問題分散プロジェクトの展開プロセスでは、サーバーの再起動後にアプリケーション(データベ...

crontab スケジュールされたタスクが実行されない理由の分析と解決

序文Linux のスケジュールされたタスクを実装する方法としては、cron、anacron、at な...

関連するプロパティのリストを含む HTML エリア イメージ ホットスポットの使用の概要

<area> タグは主にイメージマップで使用されます。イメージマップにアクティブ領域 (...

Vue-CLI マルチページディレクトリパッケージ化手順の記録

ページディレクトリ構造 デフォルトの HTML テンプレート ファイル public/index.h...

nginx のインストールが完了した後に PHP を解析できない問題の解決方法

目次方法1方法2 nginxをインストールした後、PHPコードを解析できないことがわかりました。解決...

Linux mysql5.5 を mysql5.7 にアップグレードする手順と落とし穴

目次Linux MySQL 5.5 が MySQL 5.7 にアップグレードされました1. mysq...

MySQL Innodbの主な機能挿入バッファ

目次挿入バッファとは何ですか?挿入バッファのトリガー条件は何ですか?なぜ一意のインデックスにできない...

React プロジェクトにおける TypeScript の使用の概要

序文この記事では、TS の基本的な概念ではなく、プロジェクトで TypeScript (以下、TS ...

MySQL のインデックスの種類と基本的な使用例

目次索引- 総合索引- ユニークなインデックス- 主キーインデックス- 複合インデックス- 全文索引...

protobuf の簡単な紹介と Ubuntu 16.04 環境でのインストールチュートリアル

protobufの簡単な紹介Protobuf は、Google のオープンソースのシリアル化プロトコ...

CocosCreator Huarongdaoデジタルパズルの詳しい説明

目次序文文章1. パネル2. 華容島ソリューション3. コード4. 注記序文華容路とは何ですか? 誰...