Library Affected:
workbox-sw
Browser & Platform:
Safari 12 on iOS 12
Issue or Feature Request Description:
When submitting a form that is registered with a route, I get the following error:
"NotSupportedError: ReadableStream uploading is not supported"
Everything works perfectly on Android and Chrome desktop on my Mac.
Here is the javascript, I'm using to register the routes:
const bgSyncPlugin = new workbox.backgroundSync.Plugin('ppSortMagicQueue');
workbox.routing.registerRoute(
'/Home/_SaveGallery',
workbox.strategies.networkOnly({
plugins: [bgSyncPlugin]
}),
'POST'
);
Here is the request info from the debugger Network tab:
Summary
URL: https://sortmagic.redacted.net/Home/_SaveGallery
Status: β
Source: β
Request
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept: */*
Referer: https://sortmagic.redacted.net/
Origin: https://sortmagic.redacted.net
User-Agent: Mozilla/5.0 (iPad; CPU OS 12_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1
X-Requested-With: XMLHttpRequest
Response
No response headers
Request Data
MIME Type: application/x-www-form-urlencoded; charset=UTF-8
WebsiteId: 5140
EventID: 7671
EventName
token: Cl+ndF3l7owkH1+3bcO2AJQYB2gIfDtqt65uSDzoV2t8jeZZ+pf1ncOUn/1fntxv2lUS0T11AipCNgwUxiql7MGWyfDItQXY5tVsKYHWp/IByhrTJtZde1+E2t8IC+GE
GalleryName: jQKJ17Ij8
Password
X-Requested-With: XMLHttpRequest
**And here is the console output from Workbox:**
[Error] workbox β "Network request for '/Home/_SaveGallery' threw an error."
NotSupportedError: ReadableStream uploading is not supported
fetch
(anonymous function) β workbox-core.dev.js:1400
generatorResume
step β workbox-core.dev.js:14
(anonymous function) β workbox-core.dev.js:32
initializePromise
Promise
(anonymous function) β workbox-core.dev.js:11
(anonymous function) β workbox-strategies.dev.js:822
generatorResume
step β workbox-core.dev.js:14
(anonymous function) β workbox-core.dev.js:32
initializePromise
Promise
(anonymous function) β workbox-core.dev.js:11
generatorResume
step β workbox-core.dev.js:14
(anonymous function) β workbox-core.dev.js:32
initializePromise
Promise
(anonymous function) β workbox-core.dev.js:11
handleRequest β workbox-routing.dev.js:365
(anonymous function) β workbox-routing.dev.js:835
_print (workbox-core.dev.js:132)
(anonymous function) (workbox-core.dev.js:1407)
generatorResume
step (workbox-core.dev.js:14)
(anonymous function) (workbox-core.dev.js:27)
promiseReactionJob
Thanks for your help!
The error is coming from this WebKit code.
https://stackoverflow.com/a/50952018/385997 has a workaround:
Safari doesn't seems to support fetch with a Request object having a POST method ; probably because now when you construct a Request object, the body is wrapped in a ReadableStream.
You may convert your Request object to a tuple of arguments:
const body = await request.clone().text(); const {cache, credentials, headers, integrity, mode, redirect, referrer} = request; const init = {body, cache, credentials, headers, integrity, mode, redirect, referrer}; fetch(request.url, init);
@philipwalton, do you see any downsides to switching over to using that workaround when replaying queued requests, in order to ensure Safari compatibility?
Hmmm, but this workaround assumes the requests all have text bodies, no? Currently we're constructing all replayed requests with Blob bodies to support binary files and whatnot.
OhβI hadn't looked at the code, and assumed, based on the error, that it was just using request.body directly as the BodyInit, but I didn't realize it was currently using the blob() reader:
I guess I'm curious as to what Safari considers a non-ReadableStream upload, in that case? Should we ask some folks more familiar with the Streams API?
Thanks for checking on this guys. Is there something I can do to work around this from my end or do I need to wait for an update in your code?
Hey guys! Good news I figured out the issue. While testing on another iOS device, everything worked as expected. I wanted to send you the debug info and after I connected the iPhone to my laptop via USB and started the Safari debugging console, submitted the form, the error occurred. After disconnecting, the post worked. I suspect the ReadableStream is used in the debugging process.
Please feel free to close this if you're satisfies with that solution. Thanks!
I'm happy to close in that case. We can revisit if someone else can trigger this outside of the debugging scenario you describe.
So, I notice this error today as well when looking at the JS console in Safari. It seems to be happening as part of the workbox-google-analytics package, which is using a NetworkFirst strategy and for some reason throwing a no-response WorkboxError.
@jeffposnick, any ideas?

Note: this doesn't seem to be related to background sync, at least as far as I can tell.
Actually, it does appear like the problem is exactly as described in that Stack Overflow post. These are POST requests, so service worker in Safari doesn't appear to be able to replay them.
Since, all Google Analytics requests sent with navigator.sendBeacon() are all going to be POST requests, this seems like a relatively big problem...
I'm having this same problem with Safari v12 on OSX.
This is indeed not limited to Background Sync, as @philipwalton correctly noted above. It also occurs on a regular login POST form (via https://github.com/GoogleChrome/workbox/issues/2260):

I dug into this a bit more and found the following, using https://glitch.com/edit/#!/suave-beanie as a simple reproduction.
Generally speaking, Safari has no problem sending a POST request constructed with a body.
The problem, which was accurately identified in this comment on Stack Overflow, is that Safari's behavior changes based on whether or not the Request object is logged to the console before it's being sent. Apparently, whatever code is necessary to log it is enough to convert the underlying Request object into a ReadableStream, and that means it's no longer valid when sending the POST. Additionally, you apparently need to have to have the JS console open to trigger itβeither the main console or the dedicated service worker console, depending on which context is doing the logging.
(This sounds like a bug that should be reported against WebKit, because I can't imagine that's ideal behavior.)
workbox-routing will log the Request object prior to passing it to fetch() at:
We should either remove that logging statement, or alternatively only log when it's GET request or when we know there's no body.
To summarize, this is a real bug that you can encounter in Safari for any request with a body that is handled by workbox-routing, but only if
dev bundles of Workbox which triggers extra loggingI've filed https://bugs.webkit.org/show_bug.cgi?id=203617 to track the issue in Safari.