I'm trying to call APIs from an Electron app and can't find a way of how to configure this correctly.
First a quick bit of context. The use-case is a web SPA which I would like to offer as a desktop app with minimal changes to the existing codebase. I bundle all the relevant static files produced by webpack into the Electron app (my main.js
calls win.loadFile('index.html')
), but then there are calls to APIs for data. In the codebase these are easily-identifiable URLs beginning with "/api/". This works fine when served as a web SPA but fails when packaged into Electron as it assumes it is a call to a static file.
Documentation and existing StackOverflows on the subject is sparse but I have been trying to use interceptHttpProtocol/interceptFileProtocol without much success. My first question would be is this really what I should be using in this case, or is there another mechanism?
If (and that's a big if) I should be using these interceptors, from the documentation I'm don't really understand how they work. If I wish to change a file call to http I understand it would be protocol.interceptHttpProtocol('file'...)
but I'm not 100% sure. In any case, simply doing:
protocol.interceptFileProtocol('file', (request, callback) => {
callback({ path: request.url.substr(7) });
}
(the idea here is to do nothing - recast a file call to the same file call just to test interceptor functionality) results in a blank page and a "Not allowed to load local resource" error. If I set webSecurity: false
I simply get a blank page and no error. Similar results using interceptHttpProtocol and a link to google.com.
Pointers in the right direction much appreciated.
As plan B I could use Service Workers or Webpack URL rewriting to change the URLs from relative to absolute, but that would be a bit of a hack - surely there is a "proper" way of doing this.
OK, this seems like a better method than using protocol
:
session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
if (details.url.indexOf('file://api./') == 0) { //TODO Change to regex & parametrize (optional - set default value)
//TODO Test it works with non-GET (should work - using 307 redirect)
callback({ redirectURL: `http://localhost/${details.url.substr(12)}` }); //TODO Parametrize (mandatory)
} else {
callback({}); //TODO Test this works
}
});
Using protocol
should still be valid, but I think it would be using interceptBufferProtocol
:
protocol.interceptBufferProtocol('file', (request, result) => {
if (request.url.indexOf('file://api./') == 0) {
return result(new Buffer('{}')); //TODO Call API and return Buffer response (I suppose)
} else {
// FIXME What goes here!? As in "just continue doing what you would have done"
}
});
I still have no idea how to resolve the FIXME there, so if anybody can answer that it would be much appreciated.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments