2016-11-14 8 views
3

ブラウザでカスタムリクエストヘッダーを使用してHTTP GETリクエストを作成し、結果がストリームインするときに処理する必要があります.Fetch APIは、これには理想的です。フェッチAPI、カスタムリクエストヘッダー、CORS、クロスオリジンリダイレクト

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. 
}); 

これは非常にうまくいきます。カスタムヘッダーがあるため、ブラウザはOPTIONSリクエストを使用してリクエストを/resourceにプリフライトします。私は204 No Contentと、次のヘッダーに対応するための私のサーバーを設定している:

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

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

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

Fetch API cannot load https://example.com/resource . Redirect from ' https://example.com/resource ' to ' http://some-other-origin/resource ' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.

これは予期せぬもので、私にとっては無意味です。私はブラウザがリダイレクトに従うことを期待し、この新しい場所の別の飛行前要求をしましたが、それはしませんでした。

まだ見知らぬ人は、私はこのクライアント側でハックすることができます。カスタムヘッダーを使わずにHTTPリクエストを作成し、Responseオブジェクトを見てリダイレクトした後にどこで終わったのか把握し、カスタムヘッダーで新しいターゲットで2回目のリクエストを行います。もちろんこれはすべてのケースでうまくいくわけではなく、私はむしろこのハックに頼っていません。私はむしろ適切な方法を見つけるだろう。

二つの質問:

  • クライアントがリダイレクトに従うことができるようにする適切な方法は何ですか?私は使用できるAccess-Control-*ヘッダーのいくつかの種類はありますか?
  • なぜこの制限が存在しますか?フォローされていないURLに続く、フライト前のフライトに従っていないことで防御されるセキュリティ上の問題はありますか?
+0

302レスポンスには 'Access-Control-Allow-Origin:*'ヘッダが含まれていますか? – sideshowbarker

+1

OKこれについて過去の議論を漠然と思い出して、スペックを振り返り、編集者や実装者と話して、誰かに答えを投稿させることができるかどうかを見てみましょう(あるいは、それは私自身で最初に分かった)。 – sideshowbarker

+0

http://stackoverflow.com/questions/34949492/cors-request-with-preflight-and-redirect-disallowed-workarounds/39728229#39728229とhttps://github.com/whatwg/fetch/issues/204も参照してください。 – sideshowbarker

答えて

5

プリフライトを必要とするリクエストへのリダイレクトをサポートするのは、フェッチ(CORSを定義する)に最近変更されたものです。

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

私はいくつかの実装は、その実装を調整し始めていると考えているが、これは誰に到達するのに時間がかかります。

+1

ありがとうございます。最初にこの制限の背後にある理由を知っていますか?それは単純にエラーかエッジケースでしたか?また、私がその質問で提案したより良い回避策がありますか? – Brad

+1

当時の処理モデルを把握したくはなく、実際にはリダイレクトのブロックが実際より複雑になったことを認識しませんでした。それは間違いであり、誰も本当にそれに不平を言うことはなかったので、修正には長い時間がかかりました。 (より良い回避策はありません) – Anne

+0

これについて新しい進歩はありますか? –

関連する問題