Re: [ServiceWorker] Can we replace event.default() with something less magic? (#607)

I found this discussion after being surprised by the treatment of redirects while implementing caching with service workers on our application. Since you're looking for use-cases, I'll describe ours.

We have Rails app housing a substantial single-page javascript app (SPA). I'm caching a bunch of assets for the SPA, and then my default caching strategy is to intercept fetch events and responding with a cached asset if available, falling back to network where necessary (i.e. `return cachResponse || fetch(event.request)`). However, the fact that any redirects in the fetch are not seen by the client results in some problems for log in and log out in particular, and I expect to come across more cases as I continue testing.

Authentication for our app is handled by the popular [Devise](https://github.com/plataformatec/devise) gem. A user who logs in through our home splash page will hit `/users/sign_in` and then be redirected to /app (the actual location of the SPA). But with the caching strategy described above, users will get to the app but see the address `/users/sign_in`. Now we do routing inside the SPA as well - for example you might wind up at `/app#project/5/task/10`. Now that will instead be `/users/sign_in#project/5/task/10`. Which is no longer a meaningful url that can be shared, even if it doesn't otherwise break the app.

I can get around this by being more selective about what I intercept - for example I can whitelist certain routes or only intercept fetches for e.g. `.js` and `.css` assets or whatever. But besides the fact that this making the caching logic a little more complicated, there are routes with redirects that I *do* want to handle. For example, when a user hits `/users/sign_out` (which redirects to `/`), I dump some stuff from the cache so that the app is not still available offline even after they've logged out. But this means that `/` appears as `/users/sign_out`. (And I do have fetch `users/sign_out` from the service worker because I need to make sure I'm waiting on the cache cleanup or worse things will happen.) And again, this a big app and I expect to run into more surprises like this in less obvious places.

So what do I want? When I started with `cacheResult || fetch(event.request)`, what I really wanted or expected was something like `cacheResult || event.default()` where `event.default()` means "do whatever the browser would have done otherwise", where that includes making redirects transparent to the client. That would work for the sign in case, though not the sign out case. So something like a `finalURL` or `overrideRequestURL` option sounds good too, for routes that do require some kind of special handling. I have also seen suggestions about allowing service workers to control client navigation - that sounds like a neat feature, but it also sounds like more responsibility than I want for this kind of case. I have an app that already works well, and as far as possible I want it to just keep behaving as it does already.

Thanks for all your work on this regardless!

---
Reply to this email directly or view it on GitHub:
https://github.com/slightlyoff/ServiceWorker/issues/607#issuecomment-118093909

Received on Thursday, 2 July 2015 17:05:45 UTC