Jakie ograniczenia dotyczą nieprzejrzystych odpowiedzi?

Odpowiedzi:

125

Dostęp do nagłówków / treści nieprzejrzystych odpowiedzi

Najprostszym ograniczenie wokół nieprzezroczystych odpowiedzi jest to, że nie można uzyskać informację o znaczącej powrotnej z większości właściwości w Responseklasie, jak headers, lub zadzwoń do różnych metod , które tworzą Bodyinterfejs, jak json()i text(). Jest to zgodne z czarnoskrzynkową naturą nieprzejrzystej odpowiedzi.

Używanie nieprzejrzystych odpowiedzi jako zasobów na stronie

Nieprzezroczyste odpowiedzi mogą służyć jako zasób na stronie sieci Web, ilekroć przeglądarka zezwala na użycie zasobu innego pochodzenia niż CORS. Oto podzbiór elementów, dla których poprawne są zasoby pochodzące z innych źródeł niż CORS, a tym samym nieprzezroczyste odpowiedzi, zaadaptowane z dokumentacji Mozilla Developer Network :

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

Godnym uwagi przypadek użycia, dla których odpowiedzi są nieprzezroczyste nie ważne jest dla zasobów czcionek .

Ogólnie, aby określić, czy można użyć nieprzejrzystej odpowiedzi jako określonego typu zasobu na stronie, należy sprawdzić odpowiednią specyfikację. Na przykład specyfikacja HTML wyjaśnia, że dla <script>elementów mogą być używane krzyżowe odpowiedzi inne niż CORS (tj. Nieprzezroczyste) , chociaż z pewnymi ograniczeniami, aby zapobiec wyciekaniu informacji o błędach.

Nieprzezroczyste odpowiedzi i interfejs API pamięci podręcznej

Jednym z problemów, na które programiści mogą napotkać nieprzejrzyste odpowiedzi, jest używanie ich z Cache Storage API . Istotne są dwie podstawowe informacje:

  • statusWłasnością nieprzezroczystej odpowiedź jest zawsze ustawiony0 , niezależnie od tego, czy oryginalny wniosek udało, czy nie.
  • Obie metody add()/ addAll()metody Cache Storage API będą odrzucać, jeśli odpowiedzi wynikające z któregokolwiek z żądań mają kod stanu spoza zakresu 2XX .

Z tych dwóch punktów wynika, że ​​jeśli żądanie wykonane jako część wywołania add()/ addAll()spowoduje nieprzezroczystą odpowiedź, nie zostanie ono dodane do pamięci podręcznej.

Możesz obejść ten problem, jawnie wykonując a, fetch()a następnie wywołując put()metodę z nieprzezroczystą odpowiedzią. W ten sposób skutecznie akceptujesz ryzyko, że buforowana odpowiedź mogła być błędem zwróconym przez serwer.

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

Nieprzezroczyste odpowiedzi i interfejs API navigator.storage

Aby uniknąć wycieku informacji międzydomenowych, do rozmiaru nieprzezroczystej odpowiedzi używanej do obliczania limitów przydziału pamięci (tj. Czy QuotaExceededzgłaszany jest wyjątek) i zgłaszanych przez navigator.storageAPI, dodano znaczące wypełnienie .

Szczegóły tego wypełnienia różnią się w zależności od przeglądarki, ale w przypadku Google Chrome oznacza to, że minimalny rozmiar, jaki każda pojedyncza nieprzezroczysta odpowiedź w pamięci podręcznej przyczynia się do ogólnego wykorzystania pamięci, wynosi około 7 megabajtów . Należy o tym pamiętać podczas określania liczby nieprzezroczystych odpowiedzi, które mają być buforowane, ponieważ można łatwo przekroczyć ograniczenia przydziału magazynu znacznie wcześniej, niż można by się spodziewać w oparciu o rzeczywisty rozmiar nieprzezroczystych zasobów.

Jeff Posnick
źródło
1
W rzeczywistości nie zajmuje takiej ilości miejsca w fizycznej pamięci urządzenia. To tylko wartość, która wpływa na obliczenia limitów.
Jeff Posnick,
1
Twoja odpowiedź jest nawet wymieniona w przewodniku po Workbox tutaj: developers.google.com/web/tools/workbox/guides/ ...
Dima Slivin
14
To prawda, ale napisałem ten przewodnik po Workbox :-)
Jeff Posnick
1
Czy to sprawia, że ​​używanie obrazu CDN w połączeniu z tego rodzaju pamięcią podręczną jest złym projektem? (Marnowanie przydzielonego miejsca) Czy można buforować plik pobrany z naszej domeny głównej i udostępniać go za pomocą linku (klucza) CDN? Na przykład, czy mogę skierować żądanie sieciowe do, cdn.x.com/test.jpga żądania pamięci podręcznej przejść do domeny głównej www.x.com/test.jpg.
cglacet
1
Znalazłem oszustwo wokół tego problemu, nie mam pojęcia, czy to przyzwoite rozwiązanie, ale zasadniczo zmuszam pracownika serwisu do udawania, że ​​jest to CDN. Dodaję względne adresy URL domeny do pamięci podręcznej (np., A /test.jpgnastępnie dla każdego żądania pobrania, aby cdn.x.com/test.jpgzmodyfikować adres URL z domeną źródłową (adres URL staje się www.x.com/test.jpg), używam czegoś takiego const cacheUrl = (url.hostname == 'cdn.x.com')? new URL(event.target.location.origin + url.pathname): url;:. Następnie żądam pamięci podręcznej z tym nowym adresem URL caches.match(cacheUrl), który wydaje się do pracy dobrze. Jakieś takie podejście?
cglacet