We want to serve a Docusaurus-build with Electron.
For this we are using a custom protocol that just serves the files to the Electron-Browser.
The Problem is, the Javascript that is running in the static-html build of the Docusaurus app just wont accept the url (at least that is what we think)
If we serve "doc://doc/docs/intro/index.html" it pops up for a second and afterwards the "Page Not Found"-page is shown - because the javascript does that.
Our url is "doc://doc" and our baseUrl is "/" and we can not figure out how to stop the Javascript from chaning the currently loaded page to the Page not found one.
(We disabled the Javascript and if it is disabled that error does not appear)
The problem was Electron...
You have to give the custom protocol privledge with this:
protocol.registerSchemesAsPrivileged([
{
scheme: 'doc',
privileges: { secure: true, standard: true },
},
]);
So it has actually nothing to do with Docusaurus.
Related
Usually whenever I read a blog post about PWA's, the tutorial seems to just precache every single asset. But this seems to go against the app shell pattern a bit, which as I understand is: Cache the bare necessities (only the app shell), and runtime cache as you go. (Please correct me if I understood this incorrectly)
Imagine I have this single page application, it's a simple index.html with a web component: <my-app>. That <my-app> component sets up some routes which looks a little bit like this, I'm using Vaadin router and web components, but I imagine the problem would be the same using React with React Router or something similar.
router.setRoutes([
{
path: '/',
component: 'app-main', // statically loaded
},
{
path: '/posts',
component: 'app-posts',
action: () => { import('./app-posts.js');} // dynamically loaded
},
/* many, many, many more routes */
{
path: '/offline', // redirect here when a resource is not cached and failed to get from network
component: 'app-offline', // also statically loaded
}
]);
My app may have many many routes, and may get very large. I don't want to precache all those resources straight away, but only cache the stuff I absolutely need, so in this case: my index.html, my-app.js, app-main.js, and app-offline.js. I want to cache app-posts.js at runtime, when it's requested.
Setting up runtime caching is simple enough, but my problem arises when my user visits one of the potentially many many routes that is not cached yet (because maybe the user hasn't visited that route before, so the js file may not have loaded/cached yet), and the user has no internet connection.
What I want to happen, in that case (when a route is not cached yet and there is no network), is for the user to be redirected to the /offline route, which is handled by my client side router. I could easily do something like: import('./app-posts.js').catch(() => /* redirect user to /offline */), but I'm wondering if there is a way to achieve this from workbox itself.
So in a nutshell:
When a js file hasn't been cached yet, and the user has no network, and so the request for the file fails: let workbox redirect the page to the /offline route.
Option 1 (not always useful):
As far as I can see and according to this answer, you cannot open a new window or change the URL of the browser from within the service worker. However you can open a new window only if the clients.openWindow() function is called from within the notificationclick event.
Option 2 (hardest):
You could use the WindowClient.navigate method within the activate event of the service worker however is a bit trickier as you still need to check if the file requested exists in the cache or not.
Option 3 (easiest & hackiest):
Otherwise, you could respond with a new Request object to the offline page:
const cacheOnly = new workbox.strategies.CacheOnly();
const networkFirst = new workbox.strategies.NetworkFirst();
workbox.routing.registerRoute(
/\/posts.|\/articles/,
async args => {
const offlineRequest = new Request('/offline.html');
try {
const response = await networkFirst.handle(args);
return response || await cacheOnly.handle({request: offlineRequest});
} catch (error) {
return await cacheOnly.handle({request: offlineRequest})
}
}
);
and then rewrite the URL of the browser in your offline.html file:
<head>
<script>
window.history.replaceState({}, 'You are offline', '/offline');
</script>
</head>
The above logic in Option 3 will respond to the requested URL by using the network first. If the network is not available will fallback to the cache and even if the request is not found in the cache, will fetch the offline.html file instead. Once the offline.html file is parsed, the browser URL will be replaced to /offline.
Im working on my PWA application.
So I have one problem that I can't find any info how to fix.
I use workbox with webpack InjectManifest ( but also tried webpack offline-plugin ).
When I access my webpage at the root and go offline, I can see it's working perfectly. But when I change route to '/authorize' or basically any other route and go offline, it doesn't work.
Is there any requirement that it will work only in case that we are on root path? I can't find anything about it except for this: https://github.com/quasarframework/quasar-cli/issues/131
Ok found it.
So basically it all comes to routing.
https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route
https://developers.google.com/web/tools/workbox/modules/workbox-strategies
In my case, I wanted to always serve content as for SPA so I had to add
workbox.routing.registerNavigationRoute('/index.html'); to my workbox config.
At the end it looks like this:
1) Webpack plugin:
const commonPlugins = [
new workboxPlugin.InjectManifest({
swSrc: './src/workbox-sw.js',
swDest: 'workbox-sw.js',
}),
];
2) Content of workbox-sw
/* globals workbox, self */
workbox.setConfig({
debug: true
});
workbox.core.setCacheNameDetails({
prefix: 'sneak-client',
suffix: 'v1',
precache: 'sneak-precache',
runtime: 'sneak-runtime-cache',
});
workbox.routing.registerNavigationRoute('/index.html');
workbox.precaching.precacheAndRoute(self.__precacheManifest);
I want to use gulp-webapp with php server (not the default built in one).
my gulp file looks like this, but here is the extracted part:
gulp.task('serve', ['styles'], function () {
browserSync.init("*", {
debugInfo: true,
open: true,
proxy: "localhost/nl_mobile/app"
})
});
gulp.task('watch', ['serve'], function () {
// watch for changes
gulp.watch(['app/*.html'], reload);
gulp.watch('app/styles/**/*.scss', ['styles']);
gulp.watch('app/scripts/**/*.js', ['scripts']);
gulp.watch('app/images/**/*', ['images']);
gulp.watch('bower.json', ['wiredep']);
gulp.watch('app/bower_components/**/*.scss', ['styles']);
gulp.watch('app/bower_components/**/*.js', ['scripts']);
});
The problem is, the changed content inject to the browser but it does not refresh itself, i have to refresh it manually.
I also changed this line:
// .pipe(gulp.dest('.tmp/styles'))
.pipe(gulp.dest('app/styles'))
because, i cannon't specify
server: {
baseDir: ['app', '.tmp'],
directory: true
},
because it will fire up some kind of http based server which doesn't understand php :(
In case you didn't run across the answer already, Browser Sync supports a proxy config option that can be used to reverse proxy another web server, e.g. Apache, php -S. You'll also need to watch the PHP files in your project for updates to trigger the reload in the attached browsers. Happy to expound with examples as needed.
So I know how to access both external and internal URL's in the Titanium Webview. But I have no idea how to redirect from an external url to the internal url.
I've got a file called "index.html" in the root folder, so for the webview this should work to access it:
Ti.UI.createWebView({
url: 'index.html'
});
External urls are pretty straight forward
Ti.UI.createWebView({
url: 'http://www.google.com'
});
However, when on the external url, how do I redirect to this local file? None of these work:
LOCAL?
LOCAL?
or the javascript variant
window.location = 'file:///index.html';
Any clues on how to do this?
What I discovered, in the end, are 2 possibilities to achieve this. But it can't be done through redirection.
One: Poll for a certain variable using the webview.evalJS() function
var my_data = $.login_webview.evalJS('global.data;');
Of course, it works only with strings, not with objects. So if you're passing JSON, make sure it is set as a string!
Two: Do an actual redirection server side, to another serverside page and monitor for URL change and then do evalJS() once again, but no need for polling
$.login_webview.addEventListener('load',function(e){
if (e.url.indexOf('mobile/redirect.php') > -1){
var my_data = $.login_webview.evalJS('global.data');
}
});
Just make sure, with 2 that you're actually setting the required data in Javascript using server side technology.
My main page is here:
http://www.mydomain.com/main/main.php
My login page is here:
http://www.mydomain.com/main/pages/login.php
Main.php uses ajax to fetch data in response to a tap event. This works fine until I navigate to my login page and then back to my main page. After going to the login page and back, the relative paths get messed up such that the ajax looks for server file in the wrong place.
here is the ajax:
1. function get_more_data() {
2. more_data_index += 15;
3. var formData = "index=" + more_data_index;
4. $.ajax({
5. type: "POST",
6. url: "genxml.php", // file located here: http://www.mydomain.com/main/genxml.php
7. cache: false,
8. data: formData,
9. dataType: "xml",
10. success: showFiles3,
11. error: onErrorMoreData
12. });
13. }
After I navigate back to main.php from login.php the ajax tries posting to the wrong location:
http://www.mydomain.com/main/pages/genxml.php
(genxml.php is not in the "pages" subdirectory; it's in the main directory.)
I tried updating the ajax to use an absolute path:
url: "http://www.mydomain.com/main/genxml.php"
This made the post successful, but my data parsing failed because relatives paths are used in the main file for things like images. So instead of getting images from here: http://www.mydomain.com/main/ the script was trying to get images from here: http://www.mydomain.com/main/pages/
I've found a few posts with people having similar issues, but I've not come across a solution. I've also tried reading the jquerymobile docs and it's very possible that the jquery developers attempt to cover this issue here, but I admit I don't completely understand everything on this page:
http://jquerymobile.com/demos/1.0b3/#/demos/1.0b3/docs/pages/page-navmodel.html
If anyone can help I would really appreciate it. Thanks.
P.S. This issue happens on Android and Google Chrome, but not in Firefox.
I have created a working example of what you're trying to do. You should be able to look at this and see what I've done. Be sure to checkout the master.js. I think that the key to making it work in your situation is to nest the ajax calls within the "pageshow" event to be sure that your baseURL has been updated. You can download the example at http://www.roughlybrilliant.com/stackoverflow/7372909.7z
View the example in action as it pulls in weather.xml with relative URLs.
$("div").live("pageshow", function(){
var $page = $(this);
get_more_data();
});
Why don't you use one of this:
use "../main.php" when redirecting back from login page, or
remember UrlRefer from Headers when you entering login.php and use that to redirect back to any previous page with 301