我怎样才能强制来自浏览器-window 的外部链接在 Electron 的默认浏览器中打开?

How can I force external links from browser-window to open in a default browser from Electron?

我正在使用 BrowserWindow 显示应用程序,我想强制在默认浏览器中打开外部链接。这是可能的还是我必须以不同的方式处理这个问题?

我还没有对此进行测试,但我认为这应该有效:

1) 获取 BrowserWindow

WebContents
 var wc = browserWindow.webContents;

2) 注册 WebContentwill-navigate 并拦截 navigation/link 次点击:

wc.on('will-navigate', function(e, url) {
  /* If url isn't the actual page */
  if(url != wc.getURL()) {
    e.preventDefault();
    openBrowser(url);
  } 
}

3) 使用 child_process 实现 openBrowser。 Linux 桌面示例:

var openBrowser(url) {
  require('child_process').exec('xdg-open ' + url);
}

让我知道这是否适合你!

我想出了这个,在检查了之前答案的解决方案之后。

mainWindow.webContents.on('new-window', function(e, url) {
  e.preventDefault();
  require('electron').shell.openExternal(url);
});

根据 electron spec,单击外部链接时会触发 new-window

注意:要求您在锚标签上使用 target="_blank"

如果您没有在 anchor 元素中使用 target="_blank",这可能对您有用:

  const shell = require('electron').shell;

  $(document).on('click', 'a[href^="http"]', function(event) {
    event.preventDefault();
    shell.openExternal(this.href);
  });

任何路过的人。

我的用例:

我在我的应用程序中使用 SimpleMDE,它的预览模式在同一个 window 中打开链接。我希望所有链接都在默认 OS 浏览器中打开。我根据其他答案将此片段放在我的 main.js 文件中。它在创建新的 BrowserWindow 实例后调用它。我的实例称为 mainWindow

let wc = mainWindow.webContents
wc.on('will-navigate', function (e, url) {
  if (url != wc.getURL()) {
    e.preventDefault()
    electron.shell.openExternal(url)
  }
})

检查请求的 url 是否为外部 link。如果是,则使用 shell.openExternal.

mainWindow.webContents.on('will-navigate', function(e, reqUrl) {
  let getHost = url=>require('url').parse(url).host;
  let reqHost = getHost(reqUrl);
  let isExternal = reqHost && reqHost != getHost(wc.getURL());
  if(isExternal) {
    e.preventDefault();
    electron.shell.openExternal(reqUrl);
  }
}

将其放入 renderer side js 文件中。它将在用户的默认浏览器中打开 httphttps 链接。

没有JQuery附件!不需要 target="_blank"

let shell = require('electron').shell
document.addEventListener('click', function (event) {
  if (event.target.tagName === 'A' && event.target.href.startsWith('http')) {
    event.preventDefault()
    shell.openExternal(event.target.href)
  }
})

从已接受的答案中得到改进;

  1. link 必须是 target="_blank" ;
  2. 添加 background.js(或您创建 window 的任何地方):

    window.webContents.on('new-window', function(e, url) {
      // make sure local urls stay in electron perimeter
      if('file://' === url.substr(0, 'file://'.length)) {
        return;
      }
    
      // and open every other protocols on the browser      
      e.preventDefault();
      shell.openExternal(url);
    });
    

注意: 为确保在所有应用程序 windows 中执行此行为,此代码应在每次 window 创建后 运行。

对于 Electron 5,这对我有用:

  • main.js(你创建浏览器 window 的地方),在你的主要 require 语句中包含 'shell'(通常在文件的顶部),例如:

    // Modules to control application life and create native browser window
    const {
        BrowserWindow,
        shell
    } = require('electron');
    
  • createWindow() 函数中,在 mainWindow = new BrowserWindow({ ... }) 之后添加这些行:

    mainWindow.webContents.on('new-window', function(e, url) {
        e.preventDefault();
        shell.openExternal(url);
    });
    

我通过以下步骤解决了问题

  1. const {app, BrowserWindow} = require('electron')
  2. 上添加 shell
const {app, BrowserWindow, shell} = require('electron')

  1. 设置 nativeWindowOpen 为 true
function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 1350,
    height: 880,
    webPreferences: {
      nativeWindowOpen: true,
      preload: path.join(__dirname, 'preload.js')
    },
    icon: path.join(__dirname, './img/icon.icns')
})
  1. 添加如下监听代码
  mainWindow.webContents.on('will-navigate', function(e, reqUrl) {
    let getHost = url=>require('url').parse(url).host;
    let reqHost = getHost(reqUrl);
    let isExternal = reqHost && reqHost !== getHost(wc.getURL());
    if(isExternal) {
      e.preventDefault();
      shell.openExternal(reqUrl, {});
    }
  })

参考 by 崔西萍

我倾向于在外部 .js 脚本中使用这些行:

let ele = document.createElement("a");
let url = "https://google.com";
ele.setAttribute("href", url);
ele.setAttribute("onclick", "require('electron').shell.openExternal('" + url + "')");

new-window 现在已弃用,取而代之的是 Electron 12 中的 setWindowOpenHandler(参见 https://github.com/electron/electron/pull/24517)。

所以更新的答案是:

mainWindow.webContents.setWindowOpenHandler(({ url }) => {
  shell.openExternal(url);
  return { action: 'deny' };
});