Skip to content
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

Discussion: Offline Support #680

Open
ibash opened this issue Sep 8, 2018 · 12 comments

Comments

Projects
None yet
6 participants
@ibash
Copy link

commented Sep 8, 2018

Is anyone else interested in offline support?

I'm using nativefier for Safari Books Online, and I'd like to cache the site and content so I can read anywhere. I've built offline web apps before, so I have some thoughts on how to implement this. Would anyone else be interested in this?

@ghost

This comment has been minimized.

Copy link

commented Sep 8, 2018

I would be interested.

@ibash

This comment has been minimized.

Copy link
Author

commented Sep 9, 2018

Started to work on a proof of concept.

I think this should work by:

  1. Inject a service worker into the site
  2. Use something like sw-toolbox to do a network first cache
  3. Make the routes and pre-caching customizeable

I'm running into trouble injecting the service worker (chrome doesn't want you to do that for security reasons). Here are the approaches we can try:

  1. use protocol.interceptHttpProtocol

    The caveat is that you need to use a different session to actualy send the requests. I experimented a small bit with this. I think this is still viable, but may lead to annoying edge cases.

  2. use webRequest.onBeforeRequest and redirect the service worker url

    This fails with a mysterious error. Chrome doesn't want you to do this, but it might still be viable using a custom protocol. I haven't looke into the error yet.

  3. disable security on the web contentso

    Fairly confident this would work, but I haven't tried it yet.

  4. use a proxy

    This is probably the best way to go.

  5. serve the website from a custom protocol

    If you do that then you can make that custom protocol serve the service worker.

@niutech

This comment has been minimized.

Copy link

commented Sep 12, 2018

It's a great idea to enable offline mode. You could bundle a caching proxy server in node.js, e.g. node-caching-proxy, node-http-cache, node-fishback or node-http-proxy with caching middleware, then pass all the requests through it.

@ibash

This comment has been minimized.

Copy link
Author

commented Sep 22, 2018

I have a proof of concept working on my machine using interceptStreamProtocol. Cleaning up the code and then will send a PR :)

@ibash

This comment has been minimized.

Copy link
Author

commented Sep 24, 2018

I got this mostly working but hit this bug in electron. Once that's fixed, this should work. If anyone is interested the code is here: https://github.com/ibash/nativefier/tree/offline_2

@zulli73

This comment was marked as spam.

Copy link

commented Oct 23, 2018

I'm eagerly waiting for this feature!

@ibash

This comment has been minimized.

Copy link
Author

commented Oct 24, 2018

My fix for electron should land soon: electron/electron#14887 after that I can go back to hacking on it in https://github.com/ibash/nativefier/tree/offline_2.

@puneetsl

This comment was marked as spam.

Copy link

commented Jan 11, 2019

Hey @ibash ,
any updates on this?

@ibash

This comment has been minimized.

Copy link
Author

commented Jan 11, 2019

@puneetsl proof of concept works. Electron merged my initial fix but not the backported fix: electron/electron#16209

@louguitar

This comment has been minimized.

Copy link

commented May 28, 2019

Did you ever get this working? I am looking for a way to create an offline nativfier app.

@ibash

This comment has been minimized.

Copy link
Author

commented May 28, 2019

@louguitar not all the way.

The problem I ran into was electron/electron#16421. The summary: my approach was to intercept network requests using electron's apis. If you choose to intercept there's a lot of built-in chrome functionality that gets bypassed (like cookie handling, checking certificates, etc). This leads to a whack-a-mole of trying to recreate chrome's network handling.

I haven't looked at what's changed in electron, but if there was an api that allowed injecting a service worker or the ability to both intercept and then send network requests back to chrome, that would make this trivial to implement.

@ibash

This comment has been minimized.

Copy link
Author

commented Jun 2, 2019

I found a workaround.

You can inject a service worker without disabling web security by:

  1. Enabling service workers on the filesystem scheme
  2. Creating a service worker script using the html5 filesystem api
  3. Registering the file created

The works because "filesystem:https://example.com" and "https://example.com" are considered to have the same origin. See this comment in chrome.

One gotcha was that enabling service workers for the filesystem scheme needs to be done on the command line and not with protocol.registerSchemesAsPrivileged.

I've made an example here: https://github.com/ibash/service-worker-experiment
If you clone the service-worker-experiment repo and do yarn start you will see:

  1. https://example.com is loaded
  2. A service worker is registered that's defined in service-worker-loader.js

So: With this technique we could enable injecting service workers into arbitrary sites. Once you're able to inject a service worker, you can use them to cache network requests to make a site work offline.

The only gotcha is that to make this robust we need to use the electron webRequest api to allow service workers and get rid of any CSP restrictions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.