What are the rules for standard protocols path?

Viewed 945

I can't understand how the path resolution work in electron when you register a custom protocol as standard.

I have a basic custom protocol for app folder's files:

protocol.registerSchemesAsPrivileged([
  { scheme: 'app', privileges: {
                standard: true,
                secure: true,
                supportFetchAPI: true,
                corsEnabled: true,
                bypassCSP: true
            } }
])
app.on('ready', e=> {

    protocol.registerFileProtocol('app', 
                (i,o)=> console.log(i.url)||
                        o({path: path.resolve(__dirname, i.url)})
    )
    let win = new BrowserWindow()
    win.loadURL(`app://tabbed-window.html`)

}



    <script type="module" src="utils/DOM.js"></script>

    <link rel="import" 
          href="/components/Window.html" />

    <link rel="stylesheet" type="text/css"
          href="./components/Tab.css" />


    <link rel="import" 
          href="../components/icon.html" 
            data-="themes/icons/app.svg" 
            data-fas="themes/icons/fa-solid.svg" 
            data-far="themes/icons/fa-regular.svg"
            data-fab="themes/icons/fa-brands.svg" />

On the logs I have a leading slash after the main .html file so the nested ressources relatives path are wrong, getting the html file as a folder, whatever how each file is request (./ / even ../ don't avoid the .html/ folder !! )

{
  method: 'GET',
  url: 'app://tabbed-window.html/',
  referrer: '',
  headers: {
    Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
  }
}
{
  method: 'GET',
  url: 'app://tabbed-window.html/utils/DOM.js',
  referrer: '',
  headers: {
    Origin: 'app://tabbed-window.html',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) termos/0.3.0 Chrome/80.0.3987.163 Electron/8.2.3 Safari/537.36',
    'Sec-Fetch-Dest': 'script',
    Accept: '*/*'
  }
}
{
  method: 'GET',
  url: 'app://tabbed-window.html/components/Window.html',
  referrer: '',
  headers: {
    Origin: 'app://tabbed-window.html',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) termos/0.3.0 Chrome/80.0.3987.163 Electron/8.2.3 Safari/537.36',
    'Sec-Fetch-Dest': 'unknown',
    Accept: '*/*'
  }
}
{
  method: 'GET',
  url: 'app://tabbed-window.html/components/Tab.css',
  referrer: '',
  headers: {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) termos/0.3.0 Chrome/80.0.3987.163 Electron/8.2.3 Safari/537.36',
    'Sec-Fetch-Dest': 'style',
    Accept: 'text/css,*/*;q=0.1'
  }
}
{
  method: 'GET',
  url: 'app://tabbed-window.html/components/icon.html',
  referrer: '',
  headers: {
    Origin: 'app://tabbed-window.html',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) termos/0.3.0 Chrome/80.0.3987.163 Electron/8.2.3 Safari/537.36',
    'Sec-Fetch-Dest': 'unknown',
    Accept: '*/*'
  }
}
2 Answers

The custom protocols in Electron have the same effect as the file:// protocol, wherein files are served from the local file system rather than the relative app path.

To sum up, when you use relative paths (../../), the URL is altered relative to your local filesystem, like so: file:///absolute/path/to/file. The absolute path uses the base href path (in case of angular).

The requests directed to your assets can be intercepted using intercept methods of the protocol api.

Proper URL Syntax is roughly scheme://host/path. So, you miss the host part. Use something like

win.loadURL(`app://localhost/tabbed-window.html`)

And strip the app://localhost/ prefix in the protocol handler.

Related