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をインストールするための詳細な手順

推薦する

浮遊要素によって引き起こされる問題と解決策の詳細な説明

1. 問題複数のフローティング要素は親要素の幅を拡張できず、親要素の高さが 0 になる可能性がありま...

Dockerはブリッジを追加し、IPアドレスの範囲を設定します

バイナリ docker 19.03 バージョンがインストール後に docker0 ブリッジを自動的に...

Docker クロスホストネットワークの実装 (手動)

1. Macvlan の紹介Macvlan が登場する前は、イーサネット カードに複数の IP ア...

document.getElementBy系メソッドがオブジェクトを取得できない問題を解決する

getElementByIdはオブジェクトを取得できませんブラウザがドキュメントを解析するときにはシ...

HTML での位置の使用に関する簡単な紹介

昨日 HTML を少し学んだばかりで、JD.com の検索バーを作るのが待ちきれませんでした。 作っ...

ドロップダウンメニューを表示または非表示にするJavaScript

この記事では、ドロップダウンメニューを表示および非表示にするJavaScriptの具体的なコードを参...

CSS3 でのシンプルな LED デジタル時計の実装方法

これは多くの人がやったことがあるはずです。ただうずうずして書きたかったので、時間をかけていじってダー...

Windows サービス 2016 Datacenter\Stand\Embedded アクティベーション方法 (2021)

管理者権限でcmdを実行する slmgr /ipk CB7KF-BWN84-R7R2Y-793K2-...

Linuxサーバーのディスク容量を拡張する方法

目次序文ステップ序文今日、es ログが記録されていないことに気付きました。filebeat、elas...

HTML でよく使われるタグの概要 (必読)

コンテンツ詳細タグ: <h1>~<h6>タイトルタグ<pre>テ...

グループフィールドを 1 行に書き込むための mysql group_concat メソッドの例

この記事では、MySQL group_concat を使用してグループ化されたフィールドを 1 つの...

Linux インストール MySQL チュートリアル (バイナリ配布)

このチュートリアルでは、LinuxにMySQLをインストールする詳細な手順を参考までに紹介します。具...

MySQL 5.7 で業務を停止せずに従来のレプリケーションを GTID レプリケーションに変更する例

GTID の利点により、従来のファイル POS ベースのレプリケーションを GTID ベースのレプリ...

使用状況分析を備えたMySQL

持つことの使用法having 句を使用すると、グループ化後にさまざまなデータをフィルター処理できます...