Những giới hạn nào áp dụng cho các câu trả lời không rõ ràng?


Câu trả lời:


126

Access to Opaque Responses' Headers / Body

Hạn chế đơn giản nhất xung quanh các phản hồi không rõ ràng là bạn không thể lấy lại thông tin có ý nghĩa từ hầu hết các thuộc tính của Responselớp, như headershoặc gọi các phương thức khác nhau tạo nên Bodygiao diện, như json()hoặc text(). Điều này phù hợp với bản chất hộp đen của một phản hồi không trong suốt.

Sử dụng câu trả lời mờ làm tài nguyên trên trang

Các câu trả lời không rõ ràng có thể được sử dụng làm tài nguyên trên trang web bất cứ khi nào trình duyệt cho phép sử dụng tài nguyên có nguồn gốc chéo không phải CORS. Dưới đây là một tập hợp con các phần tử mà các tài nguyên nguồn gốc chéo không phải CORS và cho các phản hồi không rõ ràng, là hợp lệ, được điều chỉnh từ tài liệu của Mạng nhà phát triển Mozilla :

  • <script>
  • <link rel="stylesheet">
  • <img>, <video><audio>
  • <object><embed>
  • <iframe>

Một trường hợp sử dụng đáng chú ý mà các phản hồi không rõ ràng không hợp lệ là đối với tài nguyên phông chữ .

In general, to determine whether you can use an opaque response as a particular type of resource on a page, check the relevant specification. For example, the HTML specification explains that non-CORS cross-origin (i.e. opaque) responses can be used for <script> elements, though with some limitations to prevent leaking error information.

Opaque Responses & the Cache Storage API

One "gotcha" that developer might run into with opaque responses involves using them with the Cache Storage API. Two pieces of background information are relevant:

  • The status property of an opaque response is always set to 0, regardless of whether the original request succeeded or failed.
  • The Cache Storage API's add()/addAll() methods will both reject if the responses resulting from any of the requests have a status code that isn't in the 2XX range.

From those two points, it follows that if the request performed as part of the add()/addAll() call results in an opaque response, it will fail to be added to the cache.

You can work around this by explicitly performing a fetch() and then calling the put() method with the opaque response. By doing so, you're effectively opting-in to the risk that the response you're caching might have been an error returned by your server.

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

Opaque Responses & the navigator.storage API

In order to avoid leakage of cross-domain information, there's significant padding added to the size of an opaque response used for calculating storage quota limits (i.e. whether a QuotaExceeded exception is thrown) and reported by the navigator.storage API.

The details of this padding vary from browser to browser, but for Google Chrome, this means that the minimum size that any single cached opaque response contributes to the overall storage usage is approximately 7 megabytes. You should keep this in mind when determining how many opaque responses you want to cache, since you could easily exceeded storage quota limitations much sooner than you'd otherwise expect based on the actual size of the opaque resources.


1
It does not actually take up that amount of space on a device's physical storage. It's just the value that contributes to the quota calculations.
Jeff Posnick

1
Your answer is even mentioned in the Workbox guide here: developers.google.com/web/tools/workbox/guides/…
Dima Slivin

14
True, but I did write that Workbox guide :-)
Jeff Posnick

1
Does that make using an image CDN in conjunction with this kind of cache a bad design? (Wasting allocated space) Is it possible to cache a file retrieved from our main domain and expose it with the CDN link (key)? For example can I have a network request go to cdn.x.com/test.jpg and cache requests go to the main domain www.x.com/test.jpg.
cglacet

1
Tôi đã tìm thấy một thủ thuật xung quanh vấn đề này, tôi không biết đó có phải là một giải pháp tốt hay không nhưng về cơ bản tôi đã khiến nhân viên dịch vụ của mình giả vờ đó là CDN. Tôi thêm các URL tương đối của miền trong bộ nhớ cache (ví dụ: /test.jpgsau đó đối với mỗi yêu cầu tìm nạp để cdn.x.com/test.jpgtôi sửa đổi URL với miền gốc (URL trở thành www.x.com/test.jpg), tôi sử dụng một cái gì đó như sau:. const cacheUrl = (url.hostname == 'cdn.x.com')? new URL(event.target.location.origin + url.pathname): url;Sau đó, tôi yêu cầu bộ nhớ cache với url mới này caches.match(cacheUrl), có vẻ như hoạt động tốt. Bất kỳ mặc dù theo cách tiếp cận này?
cglacet
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.