不透明な応答はFetchAPIの一部として定義され、CORSが有効になっていないときにリモートオリジンに対して行われたリクエストの結果を表します。
JavaScriptから、およびページ上のリソースとして、不透明な応答を使用する方法に関して、どのような実際的な制限と「落とし穴」が存在しますか?
回答:
不透明な応答のヘッダー/本文へのアクセス
不透明な回答周りの最も直接的な制限は、あなたがのほとんどから意味のある情報を取り戻すことができないということである性質の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
ます。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.storage
APIによって報告される不透明な応答のサイズに大幅なパディングが追加されています。
このパディングの詳細はブラウザごとに異なりますが、Google Chromeの場合、これは、キャッシュされた単一の不透明な応答が全体的なストレージ使用量に寄与する最小サイズが約7メガバイトであることを意味します。キャッシュする不透明な応答の数を決定するときは、これを覚えておく必要があります。不透明なリソースの実際のサイズに基づいて予想するよりもはるかに早く、ストレージクォータの制限を簡単に超える可能性があるためです。
cdn.x.com/test.jpg
メインドメインに送信し、キャッシュリクエストをメインドメインに送信することはできますかwww.x.com/test.jpg
。
/test.jpg
フェッチリクエストごとにcdn.x.com/test.jpg
、元のドメインでURLを変更します(URLはになりますwww.x.com/test.jpg
)const cacheUrl = (url.hostname == 'cdn.x.com')? new URL(event.target.location.origin + url.pathname): url;
。次のように使用します。次に、この新しいURLcaches.match(cacheUrl)
でキャッシュをリクエストします。細かい作業にどれしかし、このアプローチに。?