寒武

寒武

NginxリバースプロキシとCORSクロスオリジン問題の解決

一、前情提要#

前の記事では、ウェブサイトの読み込み速度に耐えられなくなり、CDN をウェブサイトに追加したと述べました。

https://www.xiaozhengyang.com/notes/5

その後、フォントファイルや「ブロガーが作成中の」json ファイルや png ファイルなど、いくつかの外部リソースを Upyun OSS にも追加しました。数日後、Upyun コントロールパネルでトラフィック統計を確認すると、フォントファイルのリクエストトラフィックが実際のトラフィックの 99.9% を占めていることがわかりました。約 220M ほどですが、このトラフィックは私が毎日記事を更新したりウェブサイトの速度をテストするために使用しているものです。将来的には訪問者数が増えたり、悪意のあるトラフィックがあった場合、1 ヶ月で 15G は何に使うのか想像もできません!解決策を見つける必要があります!

二、バックエンド Nginx のリバースプロキシ#

3 つの解決策があります。

  1. お金を払う
    ==直接パス==(私がお金を払うことは絶対にありません、この人生では絶対にありません〜)==
  2. 無料のオンラインフォントファイル CDN アドレスに変更する
    ==直接パス==(ほとんどのアドレスが GitHub や Jsdeliver であり、データベースが削除されてもすぐに気づくのは難しいです)
  3. バックエンドのローカルファイルを直接要求する
    ==bingo!==(私のバックエンドは家庭用ブロードバンドで、100M のアップストリーム帯域幅を活用するのはどうでしょうか?)

言葉にすれば、行動に移しましょう

Nginx でリバースプロキシを設定する際に問題が発生しました。

フロントエンドがexample.com/filesにアクセスすると、バックエンドの127.0.0.1/indexアドレスにプロキシされるように設定しました。ルールは次のように書かれています。

location ^~ /files/ {
    proxy_pass http://127.0.0.1/index; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header REMOTE-HOST $remote_addr; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    proxy_set_header X-Forwarded-Proto $scheme; 
    proxy_http_version 1.1; 
    add_header X-Cache $upstream_cache_status; 
    add_header Strict-Transport-Security "max-age=31536000"; 
    add_header Cache-Control no-cache; 
}

一見問題はなさそうですが、このアドレスにアクセスすると404 Not Foundエラーが発生します。コンソール情報を確認すると、Nginx がルーティングしたアドレスはexample.com/files/indexです。バックエンドが受け取るアドレスには、フロントエンドのアドレスが直接追加されるため、404 エラーが発生します。

この問題を解決するのは非常に簡単で、バックエンドが受け取るアドレスからフロントエンドのリバースプロキシの接尾辞filesを除外する必要があります。proxy_pass の行のリクエストアドレスの最後に/を追加するだけです。^~/files/ は、プレフィックスが user のリクエストに一致し、proxy_pass の末尾に / があるため、/files/* の後ろのパスが直接結合され、user が削除されます。

location ^~ /files/ {
    proxy_pass http://127.0.0.1/index/; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header REMOTE-HOST $remote_addr; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    proxy_set_header X-Forwarded-Proto $scheme; 
    proxy_http_version 1.1; 
    add_header X-Cache $upstream_cache_status; 
    add_header Strict-Transport-Security "max-age=31536000"; 
    add_header Cache-Control no-cache; 
}

これでバックエンドアドレスに正常にアクセスできます。

三、CORS クロスオリジン問題#

問題が解決された後、ブログのフロントエンドアドレスにアクセスすると、フォントファイルが正しく読み込まれないことがわかりました。F12を押してコンソールを確認すると、次のエラーメッセージが表示されます。

::: banner {error}
CORS ポリシーによってブロックされました:要求されたリソースに 'Access-Control-Allow-Origin' ヘッダーが存在しません。不透明な応答が必要な場合は、リクエストのモードを 'no-cors' に設定してリソースを取得してください。
:::

原因#

Note

要求されたリソースに 'Access-Control-Allow-Origin' が設定されていないため、nginx のレスポンスヘッダーに 'Access-Control-Allow-Origin' がありません。

解決策#

リクエストヘッダーの位置に以下のコードを追加するだけです。

    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
 
    if ($request_method = 'OPTIONS') {
        return 204;
    }

ステートメントの解析#

Access-Control-Allow-Origin
サーバーはデフォルトではクロスオリジンリクエストを許可しません。Nginx サーバーに Access-Control-Allow-Origin * を設定すると、サーバーはすべてのリクエスト元(Origin)を受け入れることができます。つまり、すべてのクロスオリジンリクエストを受け入れることができます。
Access-Control-Allow-Headers
次のエラーを防ぐためです。
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
このエラーは、現在のリクエストの Content-Type の値がサポートされていないことを示しています。実際には、私たちは "application/json" タイプのリクエストを送信したためです。ここで重要な概念が関係しています:プリフライトリクエスト(preflight request)については、以下の「プリフライトリクエスト」の説明をご覧ください。
Access-Control-Allow-Methods
次のエラーを防ぐためです。
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
OPTIONS に 204 を追加する
POST リクエストを送信する際に、Nginx がアクセスを拒否し続けるエラーを処理するためです。
"プリフライトリクエスト" を送信する際に、メソッド OPTIONS を使用する必要があるため、サーバーはこのメソッドを許可する必要があります。

四、完全なコード#

location ^~ /files/ {
   proxy_pass http://127.0.0.1/index/; 
   proxy_set_header Host $host; 
   proxy_set_header X-Real-IP $remote_addr; 
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
   proxy_set_header REMOTE-HOST $remote_addr; 
   proxy_set_header Upgrade $http_upgrade; 
   proxy_set_header Connection "upgrade"; 
   proxy_set_header X-Forwarded-Proto $scheme; 
   proxy_http_version 1.1; 
   add_header X-Cache $upstream_cache_status; 
   add_header Strict-Transport-Security "max-age=31536000"; 
   add_header Cache-Control no-cache; 
   add_header Access-Control-Allow-Origin *; 
   add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; 
   add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; 

   if ($request_method = 'OPTIONS') {
       return 204;
   }
}




🎉🎉🎉完了🎉🎉🎉

この記事はMix Spaceから xLog に同期されました。
元のリンクはhttps://www.xiaozhengyang.com/posts/life/nginx.htmlです。


読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。