web-dev-qa-db-ja.com

フェッチAPI、カスタムリクエストヘッダー、CORS、クロスオリジンリダイレクト

ブラウザ内のカスタムリクエストヘッダーを使用してHTTPGETリクエストを作成し、ストリーミング時に結果を処理する必要があります。FetchAPIはこれに最適です。

fetch('https://example.com/resource', {
  method: 'GET',
  headers: {
    'X-Brad-Test': 'true'
  },
  cache: 'no-store',
  mode: 'cors'
}).then((res) => {
  const reader = res.body.getReader();
  // etc.
});

これは非常にうまく機能します。カスタムヘッダーがあるため、ブラウザは/resourceへのOPTIONSリクエストでリクエストをプリフライトします。 204 No Contentと次のヘッダーで応答するようにサーバーを構成しました。

Access-Control-Allow-Headers: X-Requested-With, Range, If-Range, X-Brad-Test
Access-Control-Allow-Origin: *

ブラウザはこれに満足してからGETリクエストを行い、サーバーはデータとともに200 OKを返し、ブラウザは応答ヘッダーと本文にアクセスできるようにします。

リダイレクトがあると問題が発生します。 OPTIONSリクエストは、204 No Contentと以前と同じヘッダーで成功します。ブラウザは正しいGETリクエストを行い、サーバー上で302ヘッダー付きのLocation:を送信します。 Chromeは次のエラーをスローします:

Fetch APIを読み込めません https://example.com/resource 。 ' https://example.com/resource 'から ' http:// some-other-Origin/resource 'へのリダイレクトはCORSポリシーによってブロックされています:リクエストにはクロスオリジンリダイレクトに従うことは許可されていないプリフライト。

これは予想外で、私には無意味に思えます。ブラウザがリダイレクトに従い、この新しい場所に対して別の飛行前リクエストを実行することを期待していましたが、それは実行されませんでした。

見知らぬ人は、私がこのクライアント側をハックできるということです。カスタムヘッダーなしでHTTPリクエストを作成し、Responseオブジェクトを確認してリダイレクト後にどこに到達したかを特定し、カスタムヘッダーを使用して新しいターゲットで2番目のリクエストを作成できます。もちろん、これはすべての場合に機能するわけではなく、私はこのハックに頼りたくありません。私はむしろ適切な方法を見つけたいと思います。

2つの質問:

  • クライアントがリダイレクトに従うことを許可する適切な方法は何ですか?使用できるAccess-Control-*ヘッダーのようなものはありますか?
  • なぜこの制限が存在するのですか?フォローしていないURLでプリフライトを実行しないことで、どのようなセキュリティの問題が防止されますか?
7
Brad

プリフライトを必要とするリクエストへのリダイレクトのサポートは、Fetch(CORSを定義する)へのごく最近の変更です。

https://github.com/whatwg/fetch/commit/0d9a4db8bc02251cc9e391543bb3c1322fb882f2

一部の実装では実装の調整が始まっていると思いますが、すべての人に届くまでには少し時間がかかります。

11
Anne