ノードを使用して静的ファイルキャッシュを実装する方法

ノードを使用して静的ファイルキャッシュを実装する方法

キャッシュ

ブラウザ キャッシュとは、ブラウザが以前に要求されたファイルをキャッシュして、次回アクセス時に再利用できるようにするプロセスです。これにより、帯域幅が節約され、アクセス速度が向上し、サーバーの負荷が軽減されます。

キャッシュ位置の分類

メモリキャッシュ: メモリ内のキャッシュ。ブラウザを閉じるとクリアされ、通常はいくつかの js ライブラリを保存します。

ディスク キャッシュ: ハードディスク内のキャッシュは、ブラウザを閉じてもすぐにはクリアされません。通常、画像リソースや iconFont などのアイコン ファイル ライブラリなどの大きなファイルが保存されます。

両者の違い:

1. 読み取り速度: メモリ キャッシュは、ブラウザー タブ プロセスで現在解析されているファイルをキャッシュするため、次回使用するときにすばやく読み取ることができます。

ディスク キャッシュは、キャッシュをハード ディスク ファイルに直接書き込みます。キャッシュの読み取りには、キャッシュに保存されているハード ディスク ファイルに対する I/O (読み取り) 操作と、キャッシュ コンテンツの再解析が必要です。メモリ キャッシュよりも低速です。

2. 適時性: メモリ キャッシュはタブのプロセスに保存され、タブが閉じられるとクリアされます。

ディスク キャッシュ: いつクリアされるかはわかりません (誰かが情報を追加してくれることを願っています)

3. 優先度: メモリキャッシュはディスクキャッシュよりも大きい

大きなファイルの場合はメモリに保存されない可能性が高いですが、そうでない場合はメモリに保存されることをお勧めします。現時点では、ブラウザのキャッシュの場所をコードの観点から制御することはできないようです。

キャッシュ設定ヘッダー

キャッシュ制御

1. cache-control: max-age=10 // 10秒以内に再送信されるすべてのリクエストは、サーバーにリクエストを送信せずに、ブラウザのキャッシュを読み取り、強力なキャッシュに直接送信されます。
2. Cache-Control: no-cache //強制キャッシュを無効にします。毎回サーバーにリクエストが行われ、そのリクエストはブラウザのキャッシュにも保存されます(基本的にはネゴシエーションによってキャッシュされます)
3. Cache-Control: no-store //毎回サーバーにリクエストし、ブラウザにキャッシュしません。これはキャッシュなしと同じです。
コードをコピー

有効期限:

下位バージョンのブラウザと互換性があり、絶対時間を設定し、サーバーの現在時刻とブラウザの現在時刻を取得して比較します (通常は偏差がありますが、これは http1.0 の製品です)。同時に cache-control が存在する場合、cache-control が優先されます。

  • last-modified: キャッシュをネゴシエートするときに If-Modified-Since とペアで使用されます。If-Modified-Since リクエスト ヘッダーの値は、サーバーの last-modified レスポンス ヘッダーの値に対応します。サーバーは、要求されたリソースの変更時刻を比較します。それらが等しい場合、ネゴシエーション キャッシュがヒットし、304 が返されます。ブラウザーはキャッシュを読み取ることができます。
  • Etag: リソース識別子(フィンガープリントとも呼ばれ、通常は md5 値)。キャッシュのネゴシエーション時に使用され、ファイルが変更されたかどうかを比較します。If-None-Match とペアで表​​示されます。

Etag は主に、Last-Modified では解決できないいくつかの問題を解決するために使用されます。

1. 一部のファイルは定期的に変更される可能性がありますが、その内容は変更されません(変更時刻のみが変更されます)。このとき、クライアントがファイルが変更されたと認識して再 GET しないようにする必要があります。

2. 一部のファイルは、1 秒未満(たとえば、1 秒以内に N 回変更される)など、非常に頻繁に変更されるため、If-Modified-Since ではそのような細かい詳細をチェックできません。

3. 一部のサーバーでは、ファイルの最終変更時刻を正確に取得できません。

4. EtagとLast-modifyの両方が存在する場合のEtag優先度の比較

実際のプロジェクト: HTML ではキャッシュが許可されていません。HTML で参照される JS には、ベースとなる一意のバージョン番号があります。再度アクセスすると、最新の HTML にアクセスします。参照される JS または他のファイルのバージョン番号が変更されていない場合は、ローカル キャッシュが直接使用されます。

Nodeは静的ファイルキャッシュを実装する

ファイル構造

パブリックはテストに使用する静的リソースに対応します

強力なキャッシュ

アイデア

  • サービスの作成
  • 最初のリクエストはリクエストパスを解析し、fs.createReadStream().pipe()がファイルを読み取ります。
  • キャッシュの相対時間を強化するために、レスポンスヘッダーCache-Control: max-age=10を設定します。

コードの実装

定数 http = require("http");
url を require します。
定数 fs = require("fs");
定数パス = require("パス");
// ファイルパスを受け取り、ファイルに対応するファイルタイプ形式を返します const mime = require("mime"); //npm i mime 

定数サーバ = http.createServer((req, res) => {
  { パス名、クエリ } = url.parse(req.url, true);
  //__dirname は、現在のファイルが配置されているフォルダーの絶対パスを、要求されたパスレットと連結します。filePath = path.join(__dirname, "public", pathname);
  console.log(req.url);// 10 秒以内にページを繰り返し更新して、継続的に印刷されるかどうかを確認します。強力なキャッシュにヒットした場合は、10 秒ごとに 1 回印刷されます。// ヘッダー キャッシュ情報を設定します。指定されたキャッシュ時間内であれば、クライアントはサーバーに再度要求を開始する必要はありません。res.setHeader("Cache-Control", "max-age=10"); // キャッシュ期間を設定します。要求の現在の時刻 + max-age の優先度は、Expires よりも高くなります。res.setHeader("Expires", new Date(Date.now() + 10).toUTCString()); // 下位バージョンのブラウザーと互換性があり、絶対時刻を設定し、サーバーの現在の時刻を取得します。// 要求パスを取得して、ファイルかファイル ディレクトリかを判断します。fs.stat(filePath, function (err, statObj) {
    // URL が正しく解析されない場合、リクエストは失敗し、対応する URL リソースは見つかりません。404 が返されます。
    もし(エラー){
      ステータスコード = 404;
      res.end("見つかりません");
    } それ以外 {
      // ファイルの場合は、読み取り可能なストリーム + パイプを使用してファイルの内容を読み取り、mime を使用してファイルの内容の形式を取得し、エンコード標準を utf-8 に設定します。
      statObj.isFile() の場合 {
        fs.createReadStream(ファイルパス).pipe(res);
        res.setHeader()
          「コンテンツタイプ」、
          mime.getType(ファイルパス) + ";charset=utf-8"
        );
      } それ以外 {
        // ファイルディレクトリの場合は、ディレクトリ内の対応するindex.htmlを探します
        htmlPath = path.join(filePath, "index.html") とします。
        // fs.access は連結されたパスがアクセス可能かどうかを判定します fs.access(htmlPath, function (err) {
          もし(エラー){
            // アクセスできない設定ステータスコード 404
            ステータスコード = 404;
            res.end("見つかりません");
          } それ以外 {
            //アクセス可能。読み取り可能なストリームとパイプを使用してファイルの内容を読み取ります。fs.createReadStream(htmlPath).pipe(res);
            res.setHeader("Content-Type", "text/html;charset=utf-8");
          }
        });
      }
    }
  });
  // http://localhost:3000/ で nodemon cache.js を実行するとサービスを開始できます。 
});
server.listen(3000, () => {
  console.log("サーバー起動3000");
});

エフェクト表示

交渉キャッシュ

成功

アイデア

  • サービスの作成
  • 最初のリクエストはリクエストパスを解析し、fs.createReadStream().pipe()がファイルを読み取ります。
  • レスポンスヘッダーLast-modifiedを設定し、ブラウザに返します。
  • 再度リクエストし、ブラウザのif-last-modifiedと現在のリソース変更時間を比較します。等しい場合はネゴシエーションキャッシュにヒットし、レスポンスコード304が返されます。そうでない場合は、パスに対応する最新のリソースが返され、レスポンスコード200が返されます。

コードの実装

定数 http = require("http");
url を require します。
定数 fs = require("fs");
定数パス = require("パス");
mime は、次のコードで定義されます。


  filePath を path.join(__dirname, "public", pathname) とします。
  コンソールにログ出力します。
  fs.stat(filePath, 関数(err, statObj) {
    もし(エラー){
      ステータスコード = 404;
      res.end("見つかりません");
    } それ以外 {
      statObj.isFile() の場合 {
        // ブラウザが要求したファイルパスの変更時刻を statObj.ctime で判定する
        定数 ctime = statObj.ctime.toUTCString();
        // ブラウザのリクエスト ヘッダー if-modified-since === ファイルの最終変更時刻。ネゴシエーション キャッシュにヒットした場合は、304 が返されます。ブラウザ キャッシュ内のリソースをリクエストします if (req.headers["if-modified-since"] === ctime) {
          res.statusCode = 304; //ブラウザのキャッシュに移動してres.end(); を見つけます //
        } それ以外 {
          // if-modified-since !== ファイルの最終変更時刻の場合、応答ヘッダー Last-modified は、現在の要求ファイルの変更時刻を、次のブラウザー要求の last-modify-since の対応する値に設定します。res.setHeader("Last-modified", ctime);
          fs.createReadStream(ファイルパス).pipe(res);
          res.setHeader()
            「コンテンツタイプ」、
            mime.getType(ファイルパス) + ";charset=utf-8"
          );
        }
      } それ以外 {
        fs.access(htmlPath, 関数(err) {
          もし(エラー){
            // アクセスできない設定ステータスコード 404
            ステータスコード = 404;
            res.end("見つかりません");
          } それ以外 {
            fs.createReadStream(htmlPath).pipe(res);
            res.setHeader("Content-Type", "text/html;charset=utf-8");
          }
        });
      }
    }
  });
  // http://localhost:3000/ で nodemon cache2.js を実行するとサービスを開始できます。 
});
server.listen(3000, () => {
  console.log("サーバー起動3000");
});

エフェクト表示

console.log(req.url); は、ページが更新されるたびに実行されます。サーバーにリクエストが送信されますが、サーバーは 304 を返します。ネゴシエーション キャッシュがヒットし、ブラウザーはキャッシュされたリソースを直接読み取ることができます。

成功

要約する

ノードを使用して静的ファイル キャッシュを実装する方法に関するこの記事はこれで終わりです。ノードの静的ファイル キャッシュに関する関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

<<:  初心者がdockerにmysqlをインストールするときに遭遇するさまざまな問題

>>:  Linux でファイルの作成時間を取得する方法と実践的なチュートリアル

推薦する

Node.js管理ツールnvmの詳細なインストール手順

いいえnvmはnodejsの複数のバージョンを管理する役割を担っています。インストール: https...

Dockerコンテナイメージからコードを復元する手順

コードが失われ、コンテナ内で実行されているイメージから必要なコードを回復する必要がある場合があります...

JSはスネークゲームを実装する

目次1. 初期化構造2. 蛇の色のレンダリング3. ヘビの動き4. ヘビの死を判定する方法 ヘビの死...

MySQL 外部キー制約 (FOREIGN KEY) ケースの説明

MySQL 外部キー制約 (FOREIGN KEY) はテーブルの特別なフィールドであり、主キー制約...

js のプロトタイプ、プロトタイプ オブジェクト、プロトタイプ チェーンの包括的な分析

目次プロトタイプを理解するプロトタイプオブジェクトを理解するインスタンスプロパティとプロトタイププロ...

JavaScript 関数のパフォーマンスを測定するさまざまな方法の比較

目次概要パフォーマンス.nowコンソール.time時間精度を短縮注意事項分割して征服する入力値に注意...

小さな画像をクリックしたときに更新せずに大きな画像コードが表示されるようにLightboxを実現するためにCSSを使用する

小さな画像をクリックしたときに更新せずに大きな画像コードが表示されるようにLightboxを実現する...

1 つの記事で Apache Avro データを解析する

概要: この記事では、Avro データをシリアル化して生成し、FlinkSQL を使用して解析する方...

MySQLのさまざまなロックに関する詳細な理解

目次ロックの概要ロックの分類データベース操作の粒度データ操作の種類MySQL ロックさまざまなストレ...

jsはカスタムドロップダウンボックスを実装します

この記事の例では、カスタムドロップダウンボックスを実装するためのjsの具体的なコードを参考までに共有...

JavaScript によるダイナミッククリスマスツリーの詳細な説明

目次1. CSS のみを使用して作成したアニメーションのクリスマスツリー2. CSS のみを使用して...

Linux でソースインストールされたパッケージを簡単に削除する方法

ステップ1: Stowをインストールするこの例では CentOS を使用しているため、拡張 EPEL...

Vuex でゲッターとアクションを使用するための追加手順

予備的注釈1.Vue2.xとVue3.xの違い: Vue 3.x にはヘルパー関数はありません。 V...

MySql 5.7.17 無料インストール構成チュートリアルの詳細な説明

1. mysql-5.7.17-winx64.zip インストール パッケージをダウンロードします ...