-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(gatsby-plugin-offline): Serve the offline shell for short URLs + use no-cors for external resources #9679
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,7 +88,7 @@ exports.onPostBuild = (args, pluginOptions) => { | |
// URLs and not any files hosted on the site. | ||
// | ||
// Regex based on http://stackoverflow.com/a/18017805 | ||
navigateFallbackWhitelist: [/^[^?]*([^.?]{5}|\.html)(\?.*)?$/], | ||
navigateFallbackWhitelist: [/^([^.?]*|[^?]*\.([^.?]{5,}|html))(\?.*)?$/], | ||
navigateFallbackBlacklist: [/\?(.+&)?no-cache=1$/], | ||
cacheId: `gatsby-plugin-offline`, | ||
// Don't cache-bust JS or CSS files, and anything in the static directory | ||
|
@@ -101,7 +101,7 @@ exports.onPostBuild = (args, pluginOptions) => { | |
}, | ||
{ | ||
// Use the Network First handler for external resources | ||
urlPattern: /^https:/, | ||
urlPattern: /^https?:/, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a best practice? This seems significant in that we'll cache non-secure resources now, too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, got it!
Is there a risk here of content being cached in localhost and leading to confusion? I'd almost prefer it kept not working in localhost, but perhaps that's a naive statement? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Content is already cached on localhost to allow for testing - this is just to make it work properly for external resources which use |
||
handler: `networkFirst`, | ||
}, | ||
], | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,13 +9,19 @@ self.addEventListener(`message`, event => { | |
event.waitUntil( | ||
caches.open(cacheName).then(cache => | ||
Promise.all( | ||
resources.map(resource => | ||
cache.add(resource).catch(e => { | ||
// ignore TypeErrors - these are usually due to | ||
// external resources which don't allow CORS | ||
if (!(e instanceof TypeError)) throw e | ||
}) | ||
) | ||
resources.map(resource => { | ||
let request | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Few questions here:
Just asking these to make sure we're on the same page and I understand things! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If there are any odd errors then yes, the promise will reject the same way as before
We were already fetching everything with the old code, just never with
I haven't tested Google Analytics explicitly but yes, it should be fixed since no-cors means it can be cached. I've tested other external resources though to check it's okay. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we validate with that one just to validate we've fixed the issue this is fixing? Once that's done, I think this will be good to go and merge 🎉 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not a best practice and will quickly lead to improper caching of resources. From Workbox's own documentation:
This should probably be enabled on a case-by-case basis using the plugin's options or not at all. If the external domain allows CORS, the resource should flag it using the HTML There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @wconnorwalsh awesome; thank you for the info! This change also (could have) illustrated exactly what you reference here:
as we've seen some recent weirdness with gatsbyjs.org. I'm mostly out today, would you be interested in reverting this change and making this opt-in rather than enabled by default? If not, we'll get to it as soon as we can! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @wconnorwalsh @DSchau please note that only the changes to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've looked into this a bit more and going to create a PR shortly to revert this + fix a few more things. |
||
|
||
// Some external resources don't allow | ||
// CORS so get an opaque response | ||
if (resource.match(/^https?:/)) { | ||
request = fetch(resource, { mode: `no-cors` }) | ||
} else { | ||
request = fetch(resource) | ||
} | ||
|
||
return request.then(response => cache.put(resource, response)) | ||
}) | ||
) | ||
) | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is getting hard to follow 😱 (not your fault!)
So originally this was for capturing a file name without an extension, so if we break this apart
[^.?]*
matches anything without a dot, e.g./asdf
[^?]*\.([^.?]{5,}|html)
matches also html files?(\?.*)
matches query paramsDid I encapsulate that OK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost, but the middle is a little bit more complex:
[^.?]*
matches anything without a dot or question mark, e.g./asdf
[^?]*\.([^.?]{5,}|html)
matches anything without an extension, or with the extension html, where an extension is considered to be a dot followed by up to 4 characters (so 5 characters is not considered an extension)(\?.*)
matches query params