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

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

キャッシュ

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

キャッシュ位置の分類

メモリキャッシュ: メモリ内のキャッシュ。ブラウザを閉じるとクリアされ、通常はいくつかの 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 でファイルの作成時間を取得する方法と実践的なチュートリアル

推薦する

vue3 の setUp とリアクティブ関数の使用方法の詳細な説明

1. いつsetUpを実行するかvue3 ではメソッドを正常に使用できるようになったことは誰もが知っ...

ドメイン名、ポート、IPに基づいてnginx仮想ホストを構築する

nginxでサポートされている仮想ホストには3つの種類があります1. ドメイン名ベースの仮想ホスティ...

WeChatミニプログラムをTencent Mapsに接続する2つの方法

最近、WeChat アプレットを作成しているのですが、いくつか問題が発生しました。インターネットでい...

Centos7でmysql5.7.19のデータ保存場所を移動する方法

シナリオ: データ量が増加すると、MySQL が配置されているディスクがいっぱいになり、より大きなス...

MySQLのネストされたトランザクションで発生する問題

MySQL はネストされたトランザクションをサポートしていますが、それを実行する人は多くありません....

MySQLのデッドロックチェック処理の通常の方法

通常、デッドロックが発生すると、重みが最も小さい接続が強制終了され、ロールバックされます。ただし、最...

MySQL パーティション テーブルに関するパフォーマンス バグ

目次2. pt-pmapを使用したスタック分析3. このコラムのボトルネックポイントの分析4. パー...

CocosCreator 一般的なフレームワーク設計リソース管理

目次Cocos Creator のリソース管理に関する問題リソースの依存関係リソースの使用レスローダ...

HTML 再利用テクニック

HTML の再利用は、あまり話題に上らない言葉です。今日は、この問題を次のようにまとめたいと思います...

LinuxシステムにTomcatをインストールし、サービスの起動とシャットダウンを構成する

Linuxシステムでサービスの起動とシャットダウンを構成する1. コマンドcd /etc/init....

Linux sshのデフォルトのリモートポート番号を変更する6つの手順

Linux のデフォルトの ssh リモート ポートは 22 です。デフォルトのポートは、悪意のある...

JavaScriptページングコンポーネントの使い方の詳細な説明

ページネーションコンポーネントはWeb開発でよく使われるコンポーネントです。ページネーション機能を実...

NetEase ブログで使用されているシンプルな Web ページ コード

NetEase Blog でコードを使用する方法: まずブログにログインし、ブログのホームページの左...

【Webデザイン】E-WebTemplates の美しい海外の Web ページ テンプレート (FLASH+PSD ソース ファイル+HTML) を共有します

これらはすべて海外のE-WebTemplates WebサイトからのWebページテンプレートであり、...

Tudou.com フロントエンドの概要

1. 分業とプロセス<br />Tudou.comでは、プロジェクト開発が中核であり、誰...