【问题标题】:Service Worker is not caching every API GET (React, WorkBox)Service Worker 不会缓存每个 API GET(React、WorkBox)
【发布时间】:2021-08-31 11:50:07
【问题描述】:

我用已经编写好的 Service Worker 创建了一个新的 React 项目。我在 App 中发出 3 个不同的 API 请求。但是当我断开互联网并重新加载时,只会显示 Pokémon API 的结果。其他 2 个没有被缓存。这是App中的代码。真的很简单。

function App() {
  const [pokemon, setPokemon] = useState([])
  const [word, setWord] = useState("")
  const [color, setColor] = useState("")


  useEffect(() => {
    getAPI()
  }, [])

  const getAPI = async () => {
    const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=100")
    const data = await response.json()
    setPokemon(data.results)
    const response1 = await fetch("https://random-words-api.vercel.app/word")
    const data1 = await response1.json()
    setWord(data1[0].word)
    const response2 = await fetch("https://random-data-api.com/api/color/random_color")
    const data2 = await response2.json()
    setColor(data2.color_name)
  }

  return (
    <div className="App">
      <p>Random Word: {word}</p>
      <p>Random Color: {color}</p>
      {pokemon.map((p,i) => <p onClick={(e)=> console.log(e.target)} key={i}>{ `${i} - ${p.name} - ${p.url}`}</p>)}
    </div>
  );
}

export default App;

这是预构建的 Service Worker 文件。

/* eslint-disable no-restricted-globals */

// This service worker can be customized!
// See https://developers.google.com/web/tools/workbox/modules
// for the list of available Workbox modules, or add any other
// code you'd like.
// You can also remove this file if you'd prefer not to use a
// service worker, and the Workbox build step will be skipped.

import { clientsClaim } from 'workbox-core';
import { ExpirationPlugin } from 'workbox-expiration';
import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';

clientsClaim();

// Precache all of the assets generated by your build process.
// Their URLs are injected into the manifest variable below.
// This variable must be present somewhere in your service worker file,
// even if you decide not to use precaching. See https://cra.link/PWA
precacheAndRoute(self.__WB_MANIFEST);

// Set up App Shell-style routing, so that all navigation requests
// are fulfilled with your index.html shell. Learn more at
// https://developers.google.com/web/fundamentals/architecture/app-shell
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
registerRoute(
  // Return false to exempt requests from being fulfilled by index.html.
  ({ request, url }) => {
    // If this isn't a navigation, skip.
    if (request.mode !== 'navigate') {
      return false;
    } // If this is a URL that starts with /_, skip.

    if (url.pathname.startsWith('/_')) {
      return false;
    } // If this looks like a URL for a resource, because it contains // a file extension, skip.

    if (url.pathname.match(fileExtensionRegexp)) {
      return false;
    } // Return true to signal that we want to use the handler.

    return true;
  },
  createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
);

// An example runtime caching route for requests that aren't handled by the
// precache, in this case same-origin .png requests like those from in public/
registerRoute(
  // Add in any other file extensions or routing criteria as needed.
  ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
  new StaleWhileRevalidate({
    cacheName: 'images',
    plugins: [
      // Ensure that once this runtime cache reaches a maximum size the
      // least-recently used images are removed.
      new ExpirationPlugin({ maxEntries: 50 }),
    ],
  })
);

// This allows the web app to trigger skipWaiting via
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
self.addEventListener('message', (event) => {
  console.error("Message")
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

self.addEventListener('fetch', function (event) {
  event.respondWith(
    fetch(event.request).catch(function () {
      return caches.match(event.request);
    }),
  );
});

// Any other custom service worker logic can go here.

这种行为的原因是什么?

编辑:它非常聪明,只缓存重复的响应。但无论如何我希望它缓存最后一个值。怎么样?

【问题讨论】:

    标签: javascript reactjs progressive-web-apps service-worker workbox


    【解决方案1】:

    好的,我只看到你有一个缓存匹配,但我没有看到验证缓存的代码,例如。当没有匹配时。

    self.addEventListener('fetch', function(event) {
      console.log('Handling fetch event for', event.request.url);
    
      event.respondWith(
        caches.open(CURRENT_CACHES.font).then(function(cache) {
          return cache.match(event.request).then(function(response) {
            if (response) {
              // If there is an entry in the cache for event.request, then response will be defined
              // and we can just return it. Note that in this example, only font resources are cached.
              console.log(' Found response in cache:', response);
    
              return response;
            }
    
            // Otherwise, if there is no entry in the cache for event.request, response will be
            // undefined, and we need to fetch() the resource.
            console.log(' No response for %s found in cache. About to fetch ' +
              'from network...', event.request.url);
    
            // We call .clone() on the request since we might use it in a call to cache.put() later on.
            // Both fetch() and cache.put() "consume" the request, so we need to make a copy.
            // (see https://developer.mozilla.org/en-US/docs/Web/API/Request/clone)
            return fetch(event.request.clone()).then(function(response) {
              console.log('  Response for %s from network is: %O',
                event.request.url, response);
    
              if (response.status < 400 &&
                  response.headers.has('content-type') &&
                  response.headers.get('content-type').match(/^font\//i)) {
                // This avoids caching responses that we know are errors (i.e. HTTP status code of 4xx or 5xx).
                // We also only want to cache responses that correspond to fonts,
                // i.e. have a Content-Type response header that starts with "font/".
                // Note that for opaque filtered responses (https://fetch.spec.whatwg.org/#concept-filtered-response-opaque)
                // we can't access to the response headers, so this check will always fail and the font won't be cached.
                // All of the Google Web Fonts are served off of a domain that supports CORS, so that isn't an issue here.
                // It is something to keep in mind if you're attempting to cache other resources from a cross-origin
                // domain that doesn't support CORS, though!
                // We call .clone() on the response to save a copy of it to the cache. By doing so, we get to keep
                // the original response object which we will return back to the controlled page.
                // (see https://developer.mozilla.org/en-US/docs/Web/API/Request/clone)
                console.log('  Caching the response to', event.request.url);
                cache.put(event.request, response.clone());
              } else {
                console.log('  Not caching the response to', event.request.url);
              }
    
              // Return the original response object, which will be used to fulfill the resource request.
              return response;
            });
          }).catch(function(error) {
            // This catch() will handle exceptions that arise from the match() or fetch() operations.
            // Note that a HTTP error response (e.g. 404) will NOT trigger an exception.
            // It will return a normal response object that has the appropriate error code set.
            console.error('  Error in fetch handler:', error);
    
            throw error;
          });
        })
      );
    

    这是来自文档https://developer.mozilla.org/en-US/docs/Web/API/Cache

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-31
      • 2018-10-25
      • 2021-01-14
      • 2021-03-17
      • 2018-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多