Originally created by: segevfiner
Library Affected:
workbox-precaching
Browser & Platform:
Google Chrome 120.0.6099.199 Desktop
Issue or Feature Request Description:
On a page with an audio/video elements with preload="auto", where workbox is also set to precache the audio/video src file, sometimes the service worker ends up getting a 206 in its install event for its precache request, which leads to the following error:
workbox-0f22832a.js:2064 Uncaught (in promise) TypeError: Failed to execute 'put' on 'Cache': Partial response (status code 206) is unsupported
at StrategyHandler.cachePut (workbox-0f22832a.js:2064:23)
at async PrecacheStrategy._handleInstall (workbox-0f22832a.js:3072:27)
at async PrecacheStrategy._handle (workbox-0f22832a.js:3005:18)
at async PrecacheStrategy._getResponse (workbox-0f22832a.js:2402:22)
cachePut @ workbox-0f22832a.js:2064
I'd assume it's taking the request to preload from the browser which has a Range request, before the pre-caching is done, and sending it to the network, trying to pre-cache based on it, instead of simply dropping the uncachable partial response, and still sending a normal pre-cache request separately.
I did follow https://developer.chrome.com/docs/workbox/serving-cached-audio-and-video (P.S. I guess the cacheableResponse plugin for this is redundant nowadays?)
When reporting bugs, please include relevant JavaScript Console logs and links to public URLs at which the issue could be reproduced.
The site is private, I will create a standalone repro later on.
Originally posted by: segevfiner
Hmm, actually I probably need to add the RangeRequests plugin to the precaching handler... So that runtimeCachine example from the linked article isn't helpful for that...
Originally posted by: segevfiner
Doesn't seem to help even if I do that though...
Originally posted by: segevfiner
I guess a workaround will be to do
preload="none"and hope the user doesn't start any media before pre-caching ends... There doesn't seem to be an obvious way to add plugins toworkbox-precachingingenerateSWmode ofworkbox-buildwhich I opened a separate request for https://github.com/GoogleChrome/workbox/issues/3289.I guess a fix will be to just let such requests through to the network, without trying to precache from their response, letting the normal pre-caching still take place, or alternatively to outright to dump the
Rangeheader when getting a request that has it during theinstallphase in thePrecachingStrategy, and maybe also pass the response through plugins so the ranges plugin can modify the complete response to only return the requested range even in that case.Originally posted by: segevfiner
Maybe we want something like this in the range requests plugin or inside
workbox-precaching:Originally posted by: segevfiner
Doesn't work. The
headersreceived in the request object seem empty for this case...Originally posted by: segevfiner
We probably need to add 206 to be ignored here: https://github.com/GoogleChrome/workbox/blob/ee62b5b5b9ed321af457a2d962b2a34196a80263/packages/workbox-precaching/src/PrecacheStrategy.ts#L41
Originally posted by: segevfiner
Doesn't help, still leads to
bad-precaching-response.Originally posted by: segevfiner
So basically the browser sets a
Range: bytes=0-header withpreload="auto"and gets a full response with a 206 status, when the service worker starts after that request is complete, and tries to prefetch the file, the browser returns the 206 full content response (Racy, due to chromium coalescing the requests) which fails to be inserted into the cache with the described error. Something like this can possibly fix this:But I think
copyResponsewill fail if the request is cross origin...Originally posted by: piotr-cz
@segevfiner did you found solution to this issue?
Perhaps a plugin such as this one would help: https://github.com/GoogleChrome/workbox/issues/1644#issuecomment-1126871851
Originally posted by: segevfiner
This is something I have in some experimental branch that I didn't deploy in the end (For
injectManifestmode, as I can't seem to add precaching plugins ingenerateSWmode).Probably needs to add the full body check that it's missing to guard agains't mistakes, though I'm not sure if any partial 206 can reach it though.
Originally posted by: piotr-cz
Thanks, this seems to work (btw: videos Cache storage Status Code is
200 Partial Contentand Response-Type isdefaultinstead ofbasic)Slightly different version of similar custom plugin can be found here: https://github.com/GoogleChrome/workbox/issues/1644#issuecomment-1126871851
Originally posted by: piotr-cz
Here's is my take, which mixes your plugin (
copyResponseusage) with this one: https://github.com/GoogleChrome/workbox/issues/1644#issuecomment-1126871851I'm not sure what is the best thing to return in case when conditions for partial response not are met (
void | Response | null | undefined) so I've decided to return input and let workbox handle rest.Originally posted by: piotr-cz
To reproduce the issue:
<video src="/assets/<some-video>.mp4" />element to your app.npx serve -p 4173 dist)206 Partial Content