このエンドポイントにPostman経由でアクセスするhttp://catfacts-api.appspot.com/api/facts?number=99
と、JSON
さらに、私は create-react-app を使用しており、サーバー構成の設定を避けたいと考えています。
クライアント コードでfetch
同じことを実行しようとしていますが、次のエラーが発生します。
要求されたリソースに「Access-Control-Allow-Origin」ヘッダーが存在しません。Origin 'http://ローカルホスト:3000したがって、' はアクセスが許可されません。不透明な応答がニーズを満たす場合は、リクエストのモードを 'no-cors' に設定して、CORS を無効にしてリソースを取得します。
そこで、次のように CORS を無効にするオブジェクトを Fetch に渡そうとしています。
fetch('http://catfacts-api.appspot.com/api/facts?number=99', { mode: 'no-cors'})
.then(blob => blob.json())
.then(data => {
console.table(data);
return data;
})
.catch(e => {
console.log(e);
return e;
});
興味深いことに、私が受け取ったエラーは、実際にはこの関数の構文エラーです。fetch
{ mode: 'no-cors' } オブジェクトを削除し、別の URL を指定すると正常に動作するため、実際のエラーが壊れているかどうかはわかりません。
オブジェクトを渡そうともしました{ mode: 'opaque'}
が、上記の元のエラーが返されます。
CORS を無効にするだけでよいと思います。何が足りないのでしょうか?
ベストアンサー1
mode: 'no-cors'
魔法のようにうまくいくわけではありません。実際、これは状況を悪化させます。なぜなら、その効果の 1 つは、ブラウザに「フロントエンドの JavaScript コードが、いかなる状況でもレスポンス本文とヘッダーの内容を参照できないようにブロックする」と指示することだからです。もちろん、そんなことは望ましくありません。
フロントエンド JavaScript からのクロスオリジン リクエストでは、ブラウザはデフォルトでフロントエンド コードによるクロスオリジン リソースへのアクセスをブロックします。 がAccess-Control-Allow-Origin
応答内にある場合、ブラウザはそのブロックを緩和し、コードが応答にアクセスできるようにします。
しかし、サイトがAccess-Control-Allow-Origin
応答で「いいえ」を送信した場合、フロントエンド コードはそのサイトからの応答に直接アクセスできません。特に、指定することでこれを修正することはできませんmode: 'no-cors'
(実際、これによりフロントエンド コードが応答コンテンツにアクセスできなくなります)。
しかし、一つだけうまくいくことがあります。それは、リクエストをCORSプロキシ。
また、次の 5 つのコマンドを実行するだけで、わずか 2 ~ 3 分で独自のプロキシを Heroku に簡単にデプロイできます。
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
これらのコマンドを実行すると、たとえば で独自の CORS Anywhere サーバーが実行されることになりますhttps://cryptic-headland-94862.herokuapp.com/
。
リクエスト URL の前にプロキシ URL を付けます。例:
https://cryptic-headland-94862.herokuapp.com/https://example.com
プロキシ URL をプレフィックスとして追加すると、リクエストはプロキシ経由で行われるようになり、次のようになります。
- リクエストを に転送します
https://example.com
。 - からの応答を受信します
https://example.com
。 Access-Control-Allow-Origin
応答にヘッダーを追加します。- 追加されたヘッダーを含む応答を、要求元のフロントエンド コードに返します。
Access-Control-Allow-Origin
ブラウザは、レスポンス ヘッダーを含むレスポンスがブラウザに表示されるため、フロントエンド コードがレスポンスにアクセスできるようにします。
これは、リクエストがブラウザに CORS プリフライト リクエストの実行をトリガーするものであっても機能します。その場合、プロキシはプリフライトを成功させるために必要なおよびヘッダーもOPTIONS
送り返すためです。Access-Control-Allow-Headers
Access-Control-Allow-Methods
http://catfacts-api.appspot.com/api/facts?number=99
Postman経由でこのエンドポイントにアクセスできます
https://developer.mozilla.org/en-US/docs/Web/HTTP/アクセス制御_CORSPostman を使用してレスポンスにアクセスできるにもかかわらず、レスポンスにレスポンス ヘッダーが含まれていない限り、ブラウザーでは Web アプリで実行されているフロントエンド JavaScript コードからクロスオリジンのレスポンスにアクセスできない理由を説明しますAccess-Control-Allow-Origin
。
http://catfacts-api.appspot.com/api/facts?number=99レスポンス ヘッダーがないAccess-Control-Allow-Origin
ため、フロントエンド コードがクロスオリジンでレスポンスにアクセスすることはできません。
ブラウザはレスポンスを問題なく取得でき、Postman やブラウザ開発ツールでも確認できますが、これはブラウザがレスポンスをコードに公開するという意味ではありません。Access-Control-Allow-Origin
レスポンス ヘッダーがないため、ブラウザはレスポンスを公開しません。そのため、レスポンスを取得するにはプロキシを使用する必要があります。
プロキシはそのサイトにリクエストを送信し、応答を取得し、Access-Control-Allow-Origin
応答ヘッダーとその他の必要な CORS ヘッダーを追加して、それをリクエスト元のコードに返します。そして、ヘッダーがAccess-Control-Allow-Origin
追加された応答がブラウザーに表示されるため、ブラウザーはフロントエンド コードが実際に応答にアクセスできるようにします。
そこで私はCORSを無効にするオブジェクトをFetchに渡そうとしています
それはしたくないでしょう。誤解のないように言うと、「CORSを無効にしたい」と言うとき、実際には無効にしたいという意味のようです。同一生成元ポリシーCORS 自体は実際にそれを実現する方法です。CORS は同一生成元ポリシーを制限する方法ではなく、緩和する方法です。
しかし、いずれにせよ、ローカル環境では、ブラウザのランタイム フラグを設定してセキュリティを無効にして安全でない状態で実行したり、ブラウザ拡張機能をローカルにインストールして同一生成元ポリシーを回避したりすることはできますが、それによって状況が変わるのはローカル環境だけです。
ローカルで何を変更したとしても、アプリを使用しようとする他のユーザーは依然として同一生成元ポリシーに遭遇することになり、アプリの他のユーザーに対してこれを無効にする方法はありません。
mode: 'no-cors'
いくつかの限られたケースを除いて、実際には使用したくないでしょう。そして、その場合でも、自分が何をしているのか、そしてその効果が何なのかを正確に理解している場合に限ります。これは、この設定がmode: 'no-cors'
ブラウザに実際に伝える内容が、「いかなる状況でも、フロントエンドの JavaScript コードがレスポンス本文とヘッダーの内容を参照することをブロックする」であるためです。ほとんどの場合、明らかに、これは本当に望んでいることではありません。
の使用を検討したい場合についてはmode: 'no-cors'
、次の回答を参照してください。不透明な応答にはどのような制限が適用されますか?詳細については、こちらをご覧ください。要点は次のとおりです。
JavaScript を使用して別のオリジンのコンテンツを 、、
<script>
、、、、、要素に配置するという限定されたケース (これらの場合はオリジン間のリソースの埋め込みが許可されているため機能します) ですが、何らかの理由で、ドキュメントのマークアップでリソース URL を要素のまたは属性として使用するだけではこれを実行したくない、または実行できません。<link rel=stylesheet>
<img>
<video>
<audio>
<object>
<embed>
<iframe>
href
src
リソースに対して行いたい唯一のことは、それをキャッシュすることである場合。不透明な応答にはどのような制限が適用されますか?実際には、Service Workersを使用する場合に該当するシナリオであり、その場合に関連するAPIは次のようになります。キャッシュストレージAPI。
しかし、そのような限られたケースでも、注意すべき重要な落とし穴がいくつかあります。答えは不透明な応答にはどのような制限が適用されますか?詳細については。
私もオブジェクトを渡そうとしました
{ mode: 'opaque'}
'opaque'
リクエスト モードは存在しません。代わりに、レスポンスopaque
のプロパティのみが存在し、ブラウザは、モードで送信されたリクエストからのレスポンスにその不透明なプロパティを設定します。no-cors
しかし、偶然にも、不透明という言葉は、最終的に得られる応答の性質についてかなり明確なシグナルです。「不透明」とは、詳細をまったく見ることができない、つまり見ることを妨げていることを意味します。