Які обмеження застосовуються до непрозорих відповідей?


86

Непрозорі відповіді визначаються як частина Fetch API і представляють результат запиту, зробленого до віддаленого джерела, коли CORS не ввімкнено.

Які практичні обмеження та "недоліки" існують навколо того, як непрозорі відповіді можна використовувати як з JavaScript, так і як ресурси на сторінці?

Відповіді:


125

Доступ до заголовків / тексту непрозорих відповідей

Найбільш просте обмеження навколо непрозорих відповідей є те , що ви не можете отримати значущу інформацію назад від більшості властивостей цього Responseкласу, як headers, або викликати різні методи , які складають Bodyінтерфейс, як json()і text(). Це відповідає чорному ящику непрозорої реакції.

Використання непрозорих відповідей як ресурсів на сторінці

Непрозорі відповіді можна використовувати як ресурс на веб-сторінці, коли браузер дозволяє використовувати ресурс, що не походить від CORS. Ось підмножина елементів, для яких не є CORS перехресні джерела, а отже, непрозорі відповіді, адаптовані з документації мережі розробників Mozilla :

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

Помітним випадком використання, для якого непрозорі відповіді не є дійсними, є ресурси шрифтів .

Загалом, щоб визначити, чи можна використовувати непрозору відповідь як певний тип ресурсу на сторінці, перевірте відповідну специфікацію. Наприклад, специфікація HTML пояснює, що для <script>елементів можна використовувати відповіді, що не мають CORS (тобто непрозорі) , хоча з деякими обмеженнями для запобігання витоку інформації про помилки.

Непрозорі відповіді та API зберігання кеш-пам'яті

Одне «зачіпання», на яке розробник може натрапити з непрозорими відповідями, передбачає використання їх із API зберігання кеш-пам’яті . Доречні дві довідкові відомості:

  • statusВластивість непрозорою відповіді завжди встановлюється0 , незалежно від того, чи вдалося початковий запит або не вдалося.
  • API add()/ addAll()методи зберігання кеш-пам’яті відхилятимуть, якщо відповіді, отримані в результаті будь-якого із запитів, мають код стану, який не входить у діапазон 2XX .

З цих двох пунктів випливає, що якщо запит, виконаний як частина add()/ addAll()виклику, призводить до непрозорої відповіді, він не зможе бути доданий до кешу.

Ви можете обійти це шляхом явного виконання a, 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));

Непрозорі відповіді та API navigator.storage

Щоб уникнути витоку міждоменної інформації, до розміру непрозорої відповіді, яка використовується для обчислення обмежень квоти на зберігання (тобто, чи буде QuotaExceededвиняток), повідомляється navigator.storageAPI, додається значне доповнення .

Деталі цього доповнення відрізняються від браузера до браузера, але для Google Chrome це означає, що мінімальний розмір, який будь-яка окрема кешована непрозора відповідь сприяє загальному використанню пам’яті, становить приблизно 7 мегабайт . Ви повинні пам’ятати про це, визначаючи, скільки непрозорих відповідей ви хочете кешувати, оскільки ви можете легко перевищити обмеження квоти пам’яті набагато швидше, ніж ви очікували б, виходячи з фактичного розміру непрозорих ресурсів.


1
Це фактично не займає такої кількості місця на фізичному сховищі пристрою. Це лише величина, яка сприяє розрахунку квоти.
Jeff Posnick

1
Ваша відповідь згадується навіть у посібнику Workbox тут: developers.google.com/web/tools/workbox/guides/…
Діма Слівін,

14
Правда, але я написав цей посібник із Workbox :-)
Джеф Поснік

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.jpg), я використовую щось подібне:. const cacheUrl = (url.hostname == 'cdn.x.com')? new URL(event.target.location.origin + url.pathname): url;Потім я запитую кеш з цією новою URL-адресою caches.match(cacheUrl), що здається працювати нормально. Хоча
хтось
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.