Skip to content

Instantly share code, notes, and snippets.

@jangnezda
Created October 12, 2016 11:44
Show Gist options
  • Save jangnezda/50855df0afb3abe6dc7b315cd77bdebe to your computer and use it in GitHub Desktop.
Save jangnezda/50855df0afb3abe6dc7b315cd77bdebe to your computer and use it in GitHub Desktop.
How to load an external URL in <iframe> using Electron
/*
* By default, Electron (well, underlying Chrome browser) will reject loading external URLs
* to an <iframe>. To circumvent this limitation, we can manipulate response headers from any
* http request and feed them to the Electron window.
*
* The 'onHeadersReceived' listener is documented here:
* http://electron.atom.io/docs/api/session/#webrequestonheadersreceivedfilter-listener
*/
app.on('ready', () => {
let myWindow = new BrowserWindow({
width: 800,
height: 800,
center: true
});
// remove 'x-frame-options' header to allow embedding external pages into an 'iframe'
myWindow.webContents.session.webRequest.onHeadersReceived({}, (details, callback) => {
if(details.responseHeaders['x-frame-options']) {
delete details.responseHeaders['x-frame-options'];
}
callback({ cancel: false, responseHeaders: details.responseHeaders });
});
// replace with whatever html you want to load in your electron window
myWindow.loadURL(`file://${__dirname}/index.html`);
});
@natzar
Copy link

natzar commented Jun 10, 2019

Genius!

@rewhex
Copy link

rewhex commented Aug 20, 2019

As I can see, it's now requires urls option to be set, like this:

mainWindow.webContents.session.webRequest.onHeadersReceived(
    {urls: ['*://*/*']},
    (details, callback) => {
      if (details.responseHeaders['x-frame-options']) {
        delete details.responseHeaders['x-frame-options']
      }

      callback({
        cancel: false,
        responseHeaders: details.responseHeaders,
      })
    },
  )

@runekaagaard
Copy link

@rewhex solution works, but some servers use capitalized header names. Here is a version that supports that too:

mainWindow.webContents.session.webRequest.onHeadersReceived(
  {urls: ['*://*/*']},
  (details, callback) => {
    Object.keys(details.responseHeaders).filter(x => x.toLowerCase() === 'x-frame-options')
          .map(x => delete details.responseHeaders[x])

    callback({
      cancel: false,
      responseHeaders: details.responseHeaders,
    })
  },
)

@lijunle
Copy link

lijunle commented Aug 4, 2020

From my experience, I also need to remove content-security-policy header.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment