阻止来自“file://”源的框架访问跨域框架。

10

将 electron 从 4.1.4 升级到 5.0.0 后,我遇到了以下错误:

阻止了来自 "file://" 起源的框架访问跨起源框架。 在 HTMLIFrameElement.preload(renderer.js:31:78)

我按照这里所示添加了 new BrowserWindow({ webPreferences }) ,但这个错误仍然存在。

这是我的 index.html。

<html>
<head>
    <meta charset="UTF-8">
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
</head>
<body>
    <iframe data-bind="visible: showIframe, attr:{src:appUrl}" allow="autoplay; geolocation; microphone; camera" allowfullscreen></iframe>
</body>
<script>
    require('./renderer.js');
</script>
</html>

这是来自 main.js 的一些代码

  const {
    autoUpdater
  } = require('electron-updater');
  const platform = require('os').platform();
  const electron = require('electron');
  const fs = require('fs-extra');
  const CronJob = require('cron').CronJob;
  const {
    app,
    BrowserWindow,
    Tray,
    Menu,
    ipcMain
  } = electron;
  const path = require('path');
  const url = require('url');

  const {
    appConf, uiConf
  } = require('./config.json');


  // Deep linked url
  let deeplinkingUrl;
  //global reference for main window
  let mainWindow = null;
  let mainWindowWidth = 1100;
  let mainWindowHeight = 650;
  if (uiConf.width) {
    mainWindowWidth = uiConf.width;
  }
  if (uiConf.height) {
    mainWindowHeight = uiConf.height;
  }

  app.on('ready', (e) => {
    createWindow();
  });

  /**
   * creating main window for app
   */
  function createWindow () {
    // Create the browser window.
    mainWindow = new BrowserWindow({
      webPreferences: {
        nodeIntegration: true,
        webSecurity: false
      },
      minWidth: mainWindowWidth,
      width: mainWindowWidth,
      minHeight: mainWindowHeight,
      height: mainWindowHeight,
      icon: path.join(__dirname, appConf.appIcon),
      title: appConf.appName,
      show: false
    });

    mainWindow.once('ready-to-show', () => {
      mainWindow.show();
    });

    mainWindow.setMenu(null);

    // and load the index.html of the app.
    mainWindow.loadURL(url.format({
      pathname: path.join(__dirname, 'index.html'),
      protocol: 'file:',
      slashes: true
    }));

    // Open the DevTools.
    mainWindow.webContents.openDevTools();

  }

这是我的renderer.js文件

(function () {
  const {
    ipcRenderer,
    shell
  } = require('electron');
  const {
    appConf
  } = require('./config.json');

  const checkInternetConnected = require('check-internet-connected');

  /*
  * For screenshare
  */
  var appFrame = document.getElementsByTagName('iframe')[0];

  function preload() {
    document.getElementsByTagName('iframe')[0].contentWindow.desktopCapturer = require('electron').desktopCapturer;
    document.getElementsByTagName('iframe')[0].contentWindow.electronOpenUrl = openUrlElectron;
    document.getElementsByTagName('iframe')[0].contentWindow.deviceType = 'win';
  }

  appFrame.addEventListener('load', preload);

  function sendToIFrame(type, data) {
    appFrame.contentWindow.postMessage({ 
      type: type,
      data: data
    }, "*");
  }
  function openUrlElectron(url) {
    shell.openExternal(url);
  }
  // codes...
  // codes...
  // codes...
})();

这个应用现在运行良好,但我知道我的desktopCapturer将无法工作。我认为contentWindow脚本提升引起了这个问题,或者是其他我不知道的原因。


我添加了 new BrowserWindow({ webPreferences })。这取决于您在 webPreferences 中放置了什么。 - Seblor
2
你在 webPreferences 对象中设置了 webSecurity: false 吗? - Seblor
webSecurity: false 设置为false,但错误仍然存在。 - Freddy Daniel
2个回答

14
这是Chrome 67默认启用站点隔离安全功能后出现的已知问题,在使用包含此功能的Chromium版本的任何框架中(例如,Electron 5+),都会反映出来。

http://www.chromium.org/Home/chromium-security/site-isolation

当使用--disable-web-security进行调试时,可能还需要禁用站点隔离(使用--disable-features=IsolateOrigins,site-per-process)才能访问跨源框架。
以下是与此相关的一些开放问题。

https://github.com/electron/electron/issues/18214
https://github.com/cypress-io/cypress/issues/1951

在 Electron 5+ 中,在解决此问题之前,您可以在 app 'ready' 事件之前添加此行。
app.commandLine.appendSwitch('disable-site-isolation-trials');

这解决了问题,但使PDF查看器无法正常工作。 - m4heshd

0

我以前遇到过这个错误,通过设置nodeIntegration=false来解决它,这允许处理跨域请求。

这样做的一个副作用是进程间通信将不再起作用,但我找到了一种使用预加载脚本的方法(如果您想要详细说明,请告诉我)。


是的,我知道可以使用预加载脚本的方法。如果我使用预加载脚本,就不能使用 iframe。 - Freddy Daniel
嗨,当你说“iframe”时,我不确定你的意思,请详细说明一下? - Joshua

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接