35 ポイント 投稿者 xguru 2022-09-22 | 2件のコメント | WhatsAppで共有

CORS preflight とは?

  • 複雑なリクエストを送る前に、OPTIONS で権限があるかどうかを先に確認すること
  • ただし実際には、ほとんどのリクエストでこれが必要になる(JSON/XML ボディがある、認証情報を含む、など)
  • これがよくない理由は、実際のリクエストにかかる時間が増えること
    • OPTIONS リクエストは基本的にキャッシュできないため、CDN も通常は処理せず、リクエストはサーバーまで到達する
    • これらの値はクライアント側でキャッシュされ、デフォルトでは 5 秒しか維持されない
      • つまり、Web ページが API ポーリングを 10 秒ごとに行うなら、preflight も 10 秒ごとに 1 回発生する
    • 多くの場合、ブラウザクライアントの API レイテンシが増加し、ユーザー視点では性能が半分に落ちる
    • また、API サーバーに無駄な負荷を与え、コストも増加させる
    • 特にサーバーレスならなおさら。Lambda、Netlify Functions、Cloudflare Workers、Google Cloud Functions はいずれも関数呼び出しごとに課金されるため、この preflight もそこに含まれる

preflight 応答をキャッシュする方法

  • ブラウザ側でキャッシュして、不要な同一 preflight リクエストを送らないようにする
  • CDN レイヤーでキャッシュして、これらのリクエストを実際のバックエンドサーバーが処理しなくても応答できるようにする

ブラウザ向けの CORS キャッシュ

  • preflight 応答に次のヘッダーを追加する Access-Control-Max-Age: 86400
  • Firefox は 86400(24 時間)まで可能だが、Chromium ベースのブラウザでは 7200(2 時間)が最大値

CDN 向けの CORS キャッシュ

  • CDN またはプロキシでキャッシュするために、次のヘッダーを追加する
    Cache-Control: public, max-age=86400
    Vary: origin
  • 重要なのは、OPTIONS はデフォルトではキャッシュされるようになっていないため、標準ではないということ。ただし、ほとんどの CDN が対応している

設定例

  • AWS Lambda で CORS をキャッシュする
  • Node.js で CORS をキャッシュする
  • Python で CORS をキャッシュする
  • Java Spring で CORS をキャッシュする

2件のコメント

 
nicewook 2022-09-23

ちょうどこの部分を見ていたところだったので、興味深く拝見しました。

 
kofmania 2022-09-22

パフォーマンスが真反対に -> パフォーマンスが半分に