不透明な応答にはどのような制限が適用されますか?


89

不透明な応答FetchAPIの一部として定義され、CORSが有効になっていないときにリモートオリジンに対して行われたリクエストの結果を表します

JavaScriptから、およびページ上のリソースとして、不透明な応答を使用する方法に関して、どのような実際的な制限と「落とし穴」が存在しますか?

回答:


127

不透明な応答のヘッダー/本文へのアクセス

不透明な回答周りの最も直接的な制限は、あなたがのほとんどから意味のある情報を取り戻すことができないということである性質Responseような、クラスheaders、または様々な呼び出し方法を作るBodyようなインターフェイスを、json()またはtext()。これは、不透明な応答のブラックボックスの性質と一致しています。

ページ上のリソースとして不透明な応答を使用する

不透明な応答は、ブラウザがCORS以外のクロスオリジンリソースの使用を許可している場合はいつでも、Webページ上のリソースとして使用できます。これは、Mozilla Developer Networkのドキュメントから採用された、CORS以外のクロスオリジンリソース、およびそのための不透明な応答が有効な要素のサブセットです。

  • <script>
  • <link rel="stylesheet">
  • <img>、、、<video>および<audio>
  • <object> そして <embed>
  • <iframe>

不透明な応答がであるために顕著なユースケースではない有効であるために、フォントのリソース

一般に、ページ上の特定のタイプのリソースとして不透明な応答を使用できるかどうかを判断するには、関連する仕様を確認してください。たとえば、HTML仕様では、CORS以外のクロスオリジン(不透明)応答を<script>要素に使用できると説明されていますが、エラー情報の漏洩を防ぐための制限がいくつかあります。

不透明な応答とキャッシュストレージAPI

開発者不透明な応答で遭遇する可能性のある「落とし穴」の1つは、それらをCache StorageAPIで使用することです。2つの背景情報が関連しています。

  • status不透明な応答のプロパティは、元の要求が成功したか失敗したかに関係なく、常にに設定され0ます。
  • キャッシュストレージAPIのadd()/addAll()メソッドは、いずれかのリクエストの結果の応答に2XXの範囲外のステータスコードがある場合、両方とも拒否します

これらの2つの点から、add()/addAll()呼び出しの一部として実行された要求が不透明な応答をもたらす場合、それはキャッシュに追加されないということになります。

これを回避するには、を明示的に実行してfetch()からput()、不透明な応答でメソッドを呼び出します。そうすることで、キャッシュしている応答がサーバーから返されたエラーである可能性があるというリスクを効果的にオプトインできます。

const request = new Request('https://third-party-no-cors.com/', {mode: 'no-cors'});
// Assume `cache` is an open instance of the Cache class.
fetch(request).then(response => cache.put(request, response));

不透明な応答とnavigator.storageAPI

クロスドメイン情報の漏洩を回避するために、ストレージクォータ制限の計算(つまり、QuotaExceeded例外がスローされるかどうか)に使用され、navigator.storageAPIによって報告される不透明な応答のサイズに大幅なパディングが追加されています

このパディングの詳細はブラウザごとに異なりますが、Google Chromeの場合、これは、キャッシュされた単一の不透明な応答が全体的なストレージ使用量に寄与する最小サイズが約7メガバイトであることを意味します。キャッシュする不透明な応答の数を決定するときは、これを覚えておく必要があります。不透明なリソースの実際のサイズに基づいて予想するよりもはるかに早く、ストレージクォータの制限を簡単に超える可能性があるためです。


1
実際には、デバイスの物理ストレージでその量のスペースを占有することはありません。クォータの計算に寄与するのは値だけです。
Jeff Posnick 2018年

1
あなたの答えは、ここでも仕事箱ガイドに記載されている:developers.google.com/web/tools/workbox/guides/...を
ディマSlivin

14
本当ですが、私はそのワークボックスガイドを書きました:-)
Jeff Posnick

1
それは、この種のキャッシュと組み合わせてイメージCDNを使用することを悪い設計にしますか?(割り当てられたスペースの浪費)メインドメインから取得したファイルをキャッシュして、CDNリンク(キー)で公開することは可能ですか?たとえば、ネットワークリクエストをcdn.x.com/test.jpgメインドメインに送信し、キャッシュリクエストをメインドメインに送信することはできますかwww.x.com/test.jpg
cglacet

1
私はこの問題の周りにトリックを見つけました。それがまともな解決策であるかどうかはわかりませんが、基本的にはサービスワーカーにCDNのふりをさせます。キャッシュにドメイン相対URLを追加します(たとえば、/test.jpgフェッチリクエストごとにcdn.x.com/test.jpg、元のドメインでURLを変更します(URLはになりますwww.x.com/test.jpgconst cacheUrl = (url.hostname == 'cdn.x.com')? new URL(event.target.location.origin + url.pathname): url;。次のように使用します。次に、この新しいURLcaches.match(cacheUrl)でキャッシュをリクエストします。細かい作業にどれしかし、このアプローチに。?
cglacet
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.