fetch (), як зробити некешований запит?


77

за допомогою fetch('somefile.json'), можна вимагати отримання файлу з сервера, а не з кешу браузера?

іншими словами, за допомогою fetch(), чи можна обійти кеш браузера?


1
У вас є посилання на отримання в проекті ECMA-262 ed 6 ? Я цього не бачу. Або ви маєте на увазі рівень життя WHATWG Fetch ?
RobG

Відповіді:


110

Fetch може взяти об'єкт init, що містить багато власних налаштувань, які ви можете застосувати до запиту, це включає опцію, яка називається "заголовки".

Параметр "headers" бере об'єкт Header . Цей об'єкт дозволяє налаштувати заголовки, які ви хочете додати до свого запиту.

Додавши pragma: no-cache та cache-control: no-cache до вашого заголовка, ви змусите браузер перевірити сервер, чи не відрізняється файл від файлу, який він уже має в кеші. Ви також можете використовувати кеш-контроль: no-store, оскільки він просто забороняє браузеру та всім проміжним кешам зберігати будь-яку версію повернутої відповіді.

Ось зразок коду:

var myImage = document.querySelector('img');

var myHeaders = new Headers();
myHeaders.append('pragma', 'no-cache');
myHeaders.append('cache-control', 'no-cache');

var myInit = {
  method: 'GET',
  headers: myHeaders,
};

var myRequest = new Request('myImage.jpg');

fetch(myRequest, myInit)
  .then(function(response) {
    return response.blob();
  })
  .then(function(response) {
    var objectURL = URL.createObjectURL(response);
    myImage.src = objectURL;
  });
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ES6</title>
</head>
<body>
    <img src="">
</body>
</html>

Сподіваюся, це допомагає.


6
А як щодо використання new Requestта передачі аргументу cacheпараметрам? Я намагаюся використовувати це, але це не працює.
Мітар

1
Чи має значення капіталізація заголовків? Тобто "Кеш-контроль" проти "кеш-контроль".
Ісаак Лайман,

4
@IsaacLyman, хоча заголовки HTTP не враховують регістр, пропоную дотримуватися запропонованої документації, а саме: "Керування кешем". Довідково: developer.mozilla.org/en-US/docs/Web/HTTP/Headers
burningfuses

90

Простіше використання режимів кешування:

  // Download a resource with cache busting, to bypass the cache
  // completely.
  fetch("some.json", {cache: "no-store"})
    .then(function(response) { /* consume the response */ });

  // Download a resource with cache busting, but update the HTTP
  // cache with the downloaded resource.
  fetch("some.json", {cache: "reload"})
    .then(function(response) { /* consume the response */ });

  // Download a resource with cache busting when dealing with a
  // properly configured server that will send the correct ETag
  // and Date headers and properly handle If-Modified-Since and
  // If-None-Match request headers, therefore we can rely on the
  // validation to guarantee a fresh response.
  fetch("some.json", {cache: "no-cache"})
    .then(function(response) { /* consume the response */ });

  // Download a resource with economics in mind!  Prefer a cached
  // albeit stale response to conserve as much bandwidth as possible.
  fetch("some.json", {cache: "force-cache"})
    .then(function(response) { /* consume the response */ });

посилання: https://hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/


1
Це більш відповідна відповідь. За допомогою цих параметрів ви можете обробляти заголовки, такі як 'If-Modified-Since' та 'If-None-Match'.
Нігірі

9
Здається, це працює у Firefox (54), але не в Chrome (60). відповідь burningfuses працює.
Scimonster

1
Я протестував його, і на сьогодні (листопад 2019 р.) Цей метод, схоже, працює на Opera, Chrome та FireFox як на Windows, Linux, так і на Android. Метод спалювання запобіжників виходить з ладу принаймні в Opera.
Сопалахо де Аррієрес

У моєму випадку це не змусило перезавантажувати кеш, поки я додатково не вказавpragma: no-cache
Klesun

Це поважає CORS на відміну від виграшної відповіді.
skrat

14

Ви можете встановити 'Cache-Control': 'no-cache'в заголовку так:

return fetch(url, {
  headers: {
    'Cache-Control': 'no-cache'
  }
}).then(function (res) {
  return res.json();
}).catch(function(error) {
  console.warn('Failed: ', error);
});

5

Здавалося, жодне з рішень не спрацювало для мене добре, але цей відносно чистий (AFAICT) хак справді спрацював (адаптовано з /webmasters/93594/prevent-browser-from-caching-text-file ) :

  const URL = "http://example.com";
  const ms = Date.now();
  const data = await fetch(URL+"?dummy="+ms)
    .catch(er => game_log(er.message))
    .then(response => response.text());

Це просто додавання фіктивного параметра, який змінюється при кожному виклику запиту. Безумовно, якщо інші рішення працюють, я пропоную використовувати їх, але в моїх тестах вони не працювали в моєму випадку (наприклад, ті, що використовують Cache-Controlта pragram).


Дякую! Це єдине, що в мене спрацювало.
Dan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.