vite-pwa / vite-plugin-pwa

Zero-config PWA for Vite
https://vite-pwa-org.netlify.app/
MIT License
2.86k stars 194 forks source link

How to cache image after ajax call #664

Closed kossa closed 3 months ago

kossa commented 3 months ago

Hello,

I have some dynamic images, when the user login(online) I'll pull all products(with url of images) but I'm no showing them, it can be showing on offline, when I show the products the images are not showing, how to manually cache the images?

userquin commented 3 months ago

Try using something like this (update the urlPattern and the expiration and matchOptions):


runtimeCaching: [
{
        urlPattern: ({ url, sameOrigin }) => sameOrigin && url.pathname.match(/^\/private-images\//),
        handler: 'NetworkFirst',
        options: {
          cacheName: 'private-images-cache',
          /* check the options in the workbox-build docs*/
          expiration: {
            maxEntries: 10,
            maxAgeSeconds: 60 * 60 * 24 * 7 // <== 7 days
          },
          /* check the options in the workbox-build docs*/
          matchOptions: {
              ignoreVary: true,
              ignoreSearch: true
          },
          cacheableResponse: {
            statuses: [200]
          }
        }
      }
}
]
kossa commented 3 months ago

thank you for your response @userquin , but is does not work, may be because I forgot to tell you the image is on another url/server

userquin commented 3 months ago

Beware if the images are in another "domain", each image will be stored with some padding (7MB per image: check https://developer.chrome.com/docs/workbox/caching-resources-during-runtime#opaque_responses_and_the_navigatorstorage_api): to allow use external images you should add crossorigin to each image, the server/cdn should send proper CORs headers and you should add also proper CORS headers to every html page/js resource.

To include those images in the cache you also need to include zero (0) to the cacheableResponse.statuses array: [0,200].

kossa commented 3 months ago

After that I'll just send my xhr and automatically the images are saved in the cache?

userquin commented 3 months ago

On first request images will not be saved, since the sw must create the cache and cannot be done while intercepting the request.

Try closing the app and reopening the page: you can change the strategy to injectManifest and create the cache entry in the custom sw (when receiving the first install event).

kossa commented 3 months ago

Not sure what you mean.

But my first idea is once I get the response from the server I'll loop through the products, and add manually the images using $pwa, is it possible?

userquin commented 3 months ago

no, but you can use caches to store them in a custom cache in your app, maybe via web worker and indexedDB

You have the same problem, workbox runtime caching will do that.

kossa commented 3 months ago

You are right, I fixed it by using workbox I put: urlPattern: ({ url }) => url.pathname.match(/^\/storage\//),

Thank you @userquin I appreciated your help