記事ディレクトリ
静的リソースのキャッシュ処理
キャッシングの概要
キャッシングとは?
缓存(cache)
, 本来の意味は、一般的なランダム アクセス メモリ (RAM) よりもアクセス速度が速い高速メモリを指します. 通常、システムのメイン メモリのような DRAM テクノロジは使用されず、高価ですがより高速な SRAM テクノロジが使用されます。キャッシュの設定は、最新のすべてのコンピューター システムの高性能にとって重要な要素の 1 つです。
ウェブキャッシングとは
Web キャッシュとは、Web サーバーとクライアント (ブラウザー) の間に存在する Web リソース (html ページ、画像、js、データなど) のコピーを指します。キャッシュは、受信したリクエストに応じて出力コンテンツのコピーを保存し、次のリクエストが来たときに、同じ URL であれば、キャッシュ メカニズムに従って、コピーを直接使用してアクセス リクエストに応答するかどうかを決定します。 、または要求をソース サーバーに再度送信します。ブラウザは、訪問した Web サイトの Web ページをキャッシュすることがより一般的です. URL アドレスに再度アクセスした場合、Web ページが更新されていない場合、Web ページは再度ダウンロードされませんが、ローカルにキャッシュされた Web ページは削除されます.直接使用されます。リソースが更新されたことを Web サイトが明確に識別した場合にのみ、ブラウザーはページを再度ダウンロードします。
ウェブキャッシングの種類
- クライアントキャッシュ
- ブラウザのキャッシュ
- サーバーキャッシュ
- Nginx/Redis/Memcached など
ブラウザのキャッシュ
ネットワーク リソースを節約し、ブラウジングを高速化するために、ブラウザは最近要求されたドキュメントをユーザーのディスクに保存します. 訪問者がこのページを再度要求すると、ブラウザはローカル ディスクからドキュメントを表示できるため、ページのブラウジングを高速化できます.
ブラウザのキャッシュを使用する理由
- 最も低コストのキャッシュ実装の 1 つ
- ネットワーク帯域幅の消費を減らす
- サーバーのプレッシャーを軽減
- ネットワーク待ち時間を短縮し、ページを開く速度を上げます
ブラウザキャッシュの実行プロセス
HTTP プロトコルのページ キャッシングに関連するフィールドについて、まずそれらを理解しましょう。
ヘッダ | 例証する |
---|---|
期限切れ | キャッシュの有効期限が切れる日時 |
キャッシュ制御 | 関連する構成情報の設定とキャッシュ |
最終更新日 | リソースの最終変更時刻をリクエストする |
ETag | ファイルの MD5 値など、リクエスト変数のエンティティ タグの現在の値 |
ETag は単純に ID 番号として理解できます
-
(1) ユーザーは初めてブラウザからデータを取得するためにサーバーに要求を送信しますが、クライアントには対応するキャッシュがないため、データを取得するために要求を送信する必要があります。
-
(2)リクエストを受信した後、サーバーは成功ステータス コード 200 を返し、サーバーのデータとサーバー キャッシュのパーミッションを取得した後、対応するリソースとキャッシュの情報をレスポンス ヘッダーに添付します。
-
(3) ユーザーが同じリソースに再度アクセスすると、クライアントはブラウザのキャッシュ ディレクトリに対応するキャッシュ ファイルがあるかどうかを確認します。
-
(4) 対応するキャッシュファイルが見つからない場合は、手順 (2) へ
-
(5) キャッシュファイルが存在する場合、キャッシュファイルの有効期限が切れているかどうかを判定します。
-
(6) 有効期限が切れていない場合は、ローカル キャッシュから直接データを返して表示します (これは強力なキャッシュと呼ばれます)
-
(7) Expires が期限切れになった場合、キャッシュ ファイルが変更されたかどうかを判断する必要があります。
-
(8) 判定基準は ETag (Entity Tag) と Last-Modified の 2 通りあります。
-
(9) 判定結果が変わらない場合、サーバーは 304 を返し、キャッシュファイルから直接データを取得します (これは弱いキャッシュと呼ばれます)
-
缓存协商
(10) 変更があったと判断された場合は、再度サーバーからデータを取得し、 (キャッシュされたデータをサーバーに設定する必要があるかどうか)に従ってデータのキャッシュを実行します。
強いキャッシュと弱いキャッシュの違いは次のとおりです。
- ストロング キャッシングにより、リクエストがサーバーに送信されなくなり、ローカル キャッシュから直接取得されます
弱い
キャッシュはサーバーにリクエストを送信する必要があり、サーバーは判断後に 304 で応答し、ローカル キャッシュからアクセスされたリソースを取得し
ます、なぜ応答ステータス コードがあるのですか? よく見ると、ここの応答ステータス コード 200 が薄い灰色であることがわかります。これは、データをキャッシュするときに、アクセスされたリソースをキャッシュするだけでなく、要求ヘッダーと応答ヘッダーもキャッシュするためです )
ブラウザのキャッシュ関連の手順
Nginx はキャッシュ関連の設定を構成する必要があるため、次の手順が必要です。
コマンドを期限切れにする
expires: このディレクティブは、ページ キャッシュの役割を制御するために使用されます。このコマンドを使用して、HTTP 応答の「Expires」と「Cache-Control」を制御できます。
文法 | [変更された] 時間の 有効期限切れ epoch|max|off; |
---|---|
デフォルト | 有効期限が切れます。 |
位置 | http、サーバー、場所 |
-
time: 整数または負の数を指定できます。有効期限を指定します。単位は s です。負の数の場合、Cache-Control は no-cache です。整数または 0 の場合、Cache の値です。 -Control is max-age=time (指定した値でもあります);
- no-cache は、キャッシュを使用するときに、キャッシュの有効期限が切れているかどうかに関係なく、サーバーにリクエストを送信して、ファイルまたはリソースが変更されたかどうかを確認する必要があることを意味します (つまり、キャッシュを弱めます)。
Cache-Control の Expires と max-age=time が同じ役割を果たすことがわかりました。これは、Expires のヘッダー情報は HTTP1.0 に登場する構成ですが、Expires の値はサーバーに関連する構成と時刻であるためです. ローカル クライアントの時刻がサーバーの時刻と一致しない場合、要件が満たされない場合があります。そのため、HTTP1.1 では Cache-Control の max-age を使用して Expires の機能を置き換えていました。両方の値が存在する場合、キャッシュの有効期限が切れるかどうかを計算するために max-age の値が使用されます. 一部のブラウザーは max-age をサポートしていないため、Expires の値が計算に使用されます. したがって、通常はこれら 2 つの値を設定します。
-
エポック: Expires の値を '1 January,1970,00:00:01 GMT' (1970-01-01 00:00:00) として指定し、Cache-Control の値を no-cache として指定します
-
max: Expires の値を '31 December2037 23:59:59GMT' (2037-12-31 23:59:59) として指定し、Cache-Control の値を 10 年として指定します。
-
off: デフォルトではキャッシュしません。
たとえば、次のように構成してみ
ましょう: 次に、応答ヘッダーと前の応答ヘッダーの違いを見てみましょう。
add_header ディレクティブ
add_header コマンドは、指定された応答ヘッダーと応答値を追加するために使用されます。
文法 | add_header name 値 [常に]; |
---|---|
デフォルト | — |
位置 | http、サーバー、場所… |
- 名前: 属性名
- 値: 属性値
- always: ブラウザがサポートしているかどうかに関係なく、ヘッダー情報が追加されます
レスポンスヘッダー情報にはCache-Controlを使用し、以下の値を設定できます。
キャッシュ応答ディレクティブ:
Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>
命令 | 例証する |
---|---|
再検証が必要 | キャッシュ可能ですが、オリジンサーバーで再確認する必要があります |
キャッシュなし | キャッシュする前に有効性を確認する必要があります |
無店舗 | リクエストまたはレスポンスのコンテンツをキャッシュしない |
無変換 | プロキシはメディア タイプを変更できません |
公共 | あらゆる関係者への応答を提供できるキャッシュ |
プライベート | 特定のユーザーにのみ応答を返す |
プロキシ再検証 | 中間キャッシュ サーバーに、キャッシュされた応答の有効性を確認するように依頼します。 |
max-age=<秒> | Age の最大値に対応する |
s-maxage=<秒> | 公開キャッシュ サーバー応答の最大経過時間値 |
たとえば、リクエストまたはレスポンスのコンテンツをキャッシュしない no-store を設定してみましょう。
Nginx クロスドメインの問題解決
このコンテンツについては、主に次の側面から解決します。
- クロスドメインの問題はどのような状況で発生しますか?
- クロスドメインの問題を示す例
- 具体的な解決策は?
同一オリジン ポリシー
ブラウザの同一生成元ポリシー: これは規約であり、ブラウザのコアで最も基本的なセキュリティ機能です. ブラウザが同一生成元ポリシーを欠いている場合, ブラウザの通常の機能が影響を受ける可能性があります.
相同: 同じプロトコル、ドメイン名 (IP)、およびポートは、同じオリジンを意味します
http://192.168.200.131/user/1
https://192.168.200.131/user/1
不满足 协议不相同
http://192.168.200.131/user/1
http://192.168.200.132/user/1
不满足 IP地址不一样
http://192.168.200.131/user/1
http://192.168.200.131:8080/user/1
不满足 端口不一样
http://www.nginx.com/user/1
http://www.nginx.org/user/1
不满足 域名不一样
http://192.168.200.131/user/1
http://192.168.200.131:8080/user/1
不满足 端口不一样
http://www.nginx.org:80/user/1
http://www.nginx.org/user/1
满足 协议、端口、域名都一样
クロスドメインの問題
簡単に説明します:
サーバーは A と B の 2 つです。サーバー A のページからサーバー B にデータを取得するための非同期リクエストを送信した場合、サーバー A とサーバー B が同一生成元ポリシーを満たしていないと、クロスドメインの問題が発生します。
クロスドメインの問題はブラウザのセキュリティの問題、サーバーのセキュリティの問題ではありません。サーバー間でリクエストを送信する際にクロスドメインの問題はありません。しかし、現在はフロントエンド ページをサーバーにデプロイしており、異なるサーバーにデプロイされたフロントエンド ページがリクエストを送信するときにクロスドメインの問題が発生しています。
クロスドメインの問題のケース プレゼンテーション
クロスドメインの問題はどのような影響を与えるでしょうか? 次に、要件を通して説明します。
(1) nginxのhtmlディレクトリ下にa.htmlを新規作成
<html>
<head>
<meta charset="utf-8">
<title>跨域问题演示</title>
<script src="jquery.js"></script>
<script>
$(function(){
$("#btn").click(function(){
$.get('http://192.168.200.133:8080/getUser',function(data){
alert(JSON.stringify(data));
});
});
});
</script>
</head>
<body>
<input type="button" value="获取数据" id="btn"/>
</body>
</html>
(2) nginx.confに以下の内容を設定
server{
listen 8080;
server_name localhost;
location /getUser{
default_type application/json;
return 200 '{"id":1,"name":"TOM","age":18}';
}
}
server{
listen 80;
server_name localhost;
location /{
root html;
index index.html;
}
}
(3) ブラウザからのアクセステスト
解決
いくつかのヘッダー情報を追加するために使用できる add_header コマンドを使用します。
文法 | add_header 名前 値… |
---|---|
デフォルト | — |
位置 | http、サーバー、場所 |
ここではクロスドメインの問題を解決するために使用され、2 つのヘッダー情報を追加する必要がありますAccess-Control-Allow-Origin
。Access-Control-Allow-Methods
Access-Control-Allow-Origin: 文字通り変換された、クロスドメイン アクセスを許可する送信元アドレス情報です. 複数 (カンマ区切り) を構成するか、*
すべての送信元を表すために使用できます
Access-Control-Allow-Methods: 文字通り翻訳された、クロスドメイン アクセスを可能にするリクエスト メソッドです. 値は GET POST PUT DELETE... で、すべてまたは必要に応じて設定できます. 複数はコンマで区切られます
特定の構成
location /getUser{
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;
default_type application/json;
return 200 '{"id":1,"name":"TOM","age":18}';
}
静的リソース アンチリーチ
リソースのホットリンクとは
リソースのホットリンクとは、コンテンツが自分のサーバー上にあるのではなく、技術的な手段を通じて、他の人の制限をバイパスし、他の人のコンテンツを自分のページに配置し、最終的にユーザーに表示することを意味します. 大規模な Web サイトのスペースとトラフィックを盗むため。簡単に言えば、他人のものを使って自分のホームページを作ることです。
効果デモ
景東: https://img14.360buyimg.com/n7/jfs/t1/101062/37/2153/254169/5dcbd410E6d10ba22/4ddbd212be225fcd.jpg
バイドゥ: https://pics7.baidu.com/feed/cf1b9d16fdfaaf516f7e2011a7cda1e8f11f7a1a.jpeg?token=551979a23a0995e5e5279b8fa1a48b34&s=BD385394D2E963072FD48543BB30030
自分たちでページを用意し、そのページでこの 2 つの写真を紹介して効果を確認します。
上記の効果から、以下の画像アドレスにはホットリンクを防止する機能が追加されており、JD.com で画像を直接使用できることがわかります。
Nginx アンチリーチの実現原理:
アンチリーチングの原理を理解する前に、まず HTTP ヘッダーの Referer を学習する必要があります. ブラウザが Web サーバーにリクエストを送信すると、通常は Referer を呼び出して、その Web ページがどのページからリンクされているかをブラウザに伝えます.
バックグラウンドサーバーは、取得したReferer情報に基づいて、信頼できるWebサイトアドレスであるかどうかを判断し、信頼できる場合は引き続きアクセスを許可し、そうでない場合は403のステータス情報を返すことができます(サーバーはアクセスを拒否します)。
上記のサーバー効果をローカルでシミュレートします。
Nginx アンチリーチの具体的な実装:
valid_referers
:
Nginx は、リクエスト ヘッダーのリファラーを、valid_referers の後のコンテンツと照合します。
- 一致する場合は、$invalid_referer 変数を 0 に設定し、
- 一致するものがない場合は、$invalid_referer 変数を 1 に設定します。
照合時に大文字と小文字を区別しない
文法 | valid_referers なし|ブロックされた|server_names|string… |
---|---|
デフォルト | — |
位置 | サーバー、場所 |
-
none
: ヘッダーのリファラーが空の場合、アクセスを許可します -
blocked
: The Referer in the Header is not empty, but the value has been masqueraded by a firewall or proxy. たとえば"http://"
、などの"https://"
プロトコル ヘッダーのないリソースへのアクセスが許可されています。 -
server_names
: 特定のドメイン名または IP を指定します -
string
: 正規表現と*
文字列をサポートできます。正規表現の場合は~
、先頭で表現する必要があります。たとえば、
location ~*\.(png|jpg|gif){
valid_referers none blocked www.baidu.com 192.168.200.222 *.example.com example.* www.example.org ~\.google\.;
if ($invalid_referer){
return 403;
}
root /usr/local/nginx/html;
}
Nginx では、if の後にスペースが必要です
発生した問題: たくさんの写真があります。バッチでのホットリンクを防ぐ方法は?
ディレクトリのアンチリーチング
構成は次のとおりです。
location /images {
valid_referers none blocked www.baidu.com 192.168.200.222 *.example.com example.* www.example.org ~\.google\.;
if ($invalid_referer){
return 403;
}
root /usr/local/nginx/html;
}
このようにして、ディレクトリ内のすべてのリソースに対してアンチリーチ操作を実行できます。
発生した問題: Referer の制限は比較的粗い. たとえば、Referer を任意に追加する場合、上記の方法は制限できません。では、この問題を解決するにはどうすればよいでしょうか。
Nginxのサードパーティモジュールを使用できますngx_http_accesskey_module