Fix CORS errors in SW mode

# Conflicts:
#	www/index.html


Former-commit-id: f7ad5c8322f8bee49dcfe8d9c3700fc5f8e05606 [formerly 333ce412d4d36a992905e0819040e04f7bebea7e [formerly b55a297fbfa793caf6a472e87fb9af275992fa8f]]
Former-commit-id: 2099f2572eb40d6aa2a0c725dd0e3a6ff95575d1
Former-commit-id: 6faf8f8c02b951f5e67fb483fdb6c9cae3f9ae0a
This commit is contained in:
Jaifroid 2021-01-16 18:39:49 +00:00
parent 0183b9d4de
commit bcb44904a9
4 changed files with 26 additions and 31 deletions

View File

@ -169,6 +169,10 @@ self.addEventListener('fetch', intercept);
// Look up fetch in cache, and if it does not exist, try to get it from the network
function intercept(event) {
// Test if we're in an Electron app
// DEV: Electron uses the file:// protocol and hacks it to work with SW, but it has CORS issues when using the Fetch API to fetch local files,
// so we must bypass it here if we're fetching a local file
if (/^file:/i.test(event.request.url) && ! (regexpZIMUrlWithNamespace.test(event.request.url) && /\.zim\w{0,2}\//i.test(event.request.url))) return;
console.log('[SW] Service Worker ' + (event.request.method === "GET" ? 'intercepted ' : 'noted ') + event.request.url, event.request.method);
if (event.request.method !== "GET") return;
event.respondWith(
@ -179,7 +183,7 @@ function intercept(event) {
function () {
// The response was not found in the cache so we look for it on the server
if (/\.zim\w{0,2}\//i.test(event.request.url) && regexpZIMUrlWithNamespace.test(event.request.url)) {
if (imageDisplay !== 'all' && /(^|\/)[IJ]\/.*\.(jpe?g|png|svg|gif)($|[?#])(?!kiwix-display)/i.test(event.request.url)) {
if (imageDisplay !== 'all' && /(^|\/)[IJ]\/.*\.(jpe?g|png|svg|gif|webp)($|[?#])(?!kiwix-display)/i.test(event.request.url)) {
// If the user has disabled the display of images, and the browser wants an image, respond with empty SVG
// A URL with "?kiwix-display" query string acts as a passthrough so that the regex will not match and
// the image will be fetched by app.js
@ -223,6 +227,8 @@ function intercept(event) {
msgEvent.data.imageDisplay : imageDisplay;
var headers = new Headers();
if (contentLength) headers.set('Content-Length', contentLength);
// Prevent CORS issues in PWAs
if (contentLength) headers.set('Access-Control-Allow-Origin', '*');
if (contentType) headers.set('Content-Type', contentType);
// Test if the content is a video or audio file
// See kiwix-js #519 and openzim/zimwriterfs #113 for why we test for invalid types like "mp4" or "webm" (without "video/")

View File

@ -1,8 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Placeholder for injecting an article into the iframe</title>
</head>
<body></body>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src file: data: blob: 'unsafe-inline' 'unsafe-eval';">
<title>Placeholder for injecting an article into the iframe</title>
</head>
<body></body>
</html>

View File

@ -6,6 +6,7 @@
<title>Kiwix JS for Windows</title>
<meta name="description" content="Offline Wikipedia reader">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="default-src file: data: blob: 'unsafe-inline' 'unsafe-eval';">
<meta name="theme-color" content="black">
<!--
Kiwix (offline Wikipedia reader) - HTML5/Javascript version

View File

@ -1444,9 +1444,15 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
var tmpMessageChannel = new MessageChannel();
tmpMessageChannel.port1.onmessage = handleMessageChannelMessage;
// Send the init message to the ServiceWorker, with this MessageChannel as a parameter
if (navigator.serviceWorker.controller) navigator.serviceWorker.controller.postMessage({
'action': 'init'
}, [tmpMessageChannel.port2]);
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
'action': 'init'
}, [tmpMessageChannel.port2]);
} else {
console.error('The Service Worker is active but is not controlling the current page! We have to reload.');
window.location.reload();
return;
}
messageChannel = tmpMessageChannel;
// Schedule to do it again regularly to keep the 2-way communication alive.
// See https://github.com/kiwix/kiwix-js/issues/145 to understand why
@ -1467,27 +1473,8 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
if (value === 'jquery') {
// Because the "outer" Service Worker still runs in a PWA app, we don't actually disable the SW in this context, but it will no longer
// be intercepting requests
if ('serviceWorker' in navigator && /\/\/(localhost|kiwix.github.io)\//i.test(window.location.href)) {
if ('serviceWorker' in navigator) {
serviceWorkerRegistration = null;
} else {
if (isServiceWorkerReady()) {
// We need to disable the ServiceWorker
// Unregistering it does not seem to work as expected : the ServiceWorker
// is indeed unregistered but still active...
// So we have to disable it manually (even if it's still registered and active)
navigator.serviceWorker.controller.postMessage({
'action': 'disable'
});
messageChannel = null;
// If we're in electron, completely remove the SW (but we need to keep it active if we're in a PWA)
if (typeof window.fs !== 'undefined') {
navigator.serviceWorker.getRegistrations().then(function (registrations) {
registrations.forEach(function (registration) {
registration.unregister();
});
});
}
}
}
refreshAPIStatus();
} else if (value === 'serviceworker') {