在我的设置中,我尝试了shell.openExternal('http://example.com')
和shell.openItem('http://example.com')
并且都在后台打开了网站。
我最终在 Win32 上使用了child_process.execSync('start http://example.com')
,在 Darwin 上使用child_process.execSync('open http://example.com')
,因此浏览器实际上会弹出并获得焦点。
在 Linux 上,您可以使用 xdg-open:
child_process.execSync('xdg-open http://example.com')
我实际上决定使用node-open 。 如果你不想搞乱逃逸之类的,你应该试一试。
伙计们,但您的解决方案很棒,但我想知道如何拦截尝试打开“ http://someurl.com ”之类的shell.openExternal
打开? Service Worker 只允许捕获对同一域中文件的请求。 有能力做到这一点吗? /cc @maxogden @AlicanC
与@havenchyk相同的问题,有没有办法告诉电子默认打开外部链接?
如果您的应用仅使用一个窗口,并且您可以保证应用中的每个外部链接都在新窗口中打开(例如通过target="_blank"
),您可以执行以下操作:
webContents.on('new-window', function(event, url){
event.preventDefault();
open(url);
});
其中webContents
是您的主要 BrowserWindow 的 webContents,而open
是一个在您的浏览器中打开 url 的函数(我使用了 AlicanC 推荐的node-open )。
如果在单击 _any_ 链接时触发了一个事件,那就太好了,这样应用程序就可以决定它是否应该在浏览器中打开,但如果存在这样的事件,我还没有找到。
我在 SO 上找到了这个代码片段:
var shell = require('electron').shell;
//open links externally by default
$(document).on('click', 'a[href^="http"]', function(event) {
event.preventDefault();
shell.openExternal(this.href);
});
将它放在我的主索引文件中,据我所知,它似乎可以正常工作,即使对于动态生成的链接也是如此。 我对电子太菜了,不知道这是否有任何我应该注意的缺点。 想法?
我正在使用这段代码:
var handleRedirect = (e, url) => {
if(url != webContents.getURL()) {
e.preventDefault()
require('electron').shell.openExternal(url)
}
}
webContents.on('will-navigate', handleRedirect)
webContents.on('new-window', handleRedirect)
首先声明一个生成过程
`app.controller('GuideCtrl', ['$scope', ($scope)=>{
const spawn = require('child_process').spawn;
$scope.openBrowser=(url)=>{
let exec = spawn('explore', [url], {});
exec.stdout.on('data', (data)=> {
console.log('stdout: ' + data)
});
}
}])`
在调用方法之前
<a ng-click="openBrowser('https://google.com')">Goto google</a>
shell.openExternal
有任何安全问题吗? 例如,如果链接脱离网络,则原始网络数据将传递给shell.openExternal
或上述任何其他函数。 shell.openExternal
是否确保不会发生任何不好的事情? 我需要过滤模式吗?
基于来自@rubencodes的代码,我使用了:
const shell = require('electron').shell;
$('.open-in-browser').click((event) => {
event.preventDefault();
shell.openExternal(event.target.href);
});
然后,您只需要将“在浏览器中打开”类拖放到要在浏览器中打开的每个元素。
这是一个不需要 JQuery 的,以防其他人正在寻找它。 它会在外部浏览器中自动打开以“http”开头的任何链接。
把它放在你的渲染器进程中:
// Open all links in external browser
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)
}
})
如果您希望所有<a>
标签在默认浏览器中打开,请在您的 main.ts 中尝试:
const shell = require('electron').shell;
mainWin.webContents.on('will-navigate', (event, url) => {
event.preventDefault()
shell.openExternal(url)
});
这假设您有一个像我这样的单页应用程序。 如果没有,您需要进行一些额外的消毒。
我只想重申,在没有白名单的用户内容中使用它可能是一个巨大的安全漏洞。 我不知道所有各种方案的作用以及它们的输入是什么,但作为一个简单的例子,像这样的链接
<a href="imessage:hello">click me</a>
将在 macOS 上的 Chrome 和 Safari 中提示用户,但使用上面的代码 Electron 只会打开应用程序。
几乎感觉 Electron 本身应该默认在这里更安全,而不是让每个程序员自己弄清楚如何使其安全。
至少你可能想要类似的东西
function isSafeishURL(url) {
return url.startsWith('http:') || url.startsWith('https:');
}
mainWin.webContents.on('will-navigate', (event, url) => {
event.preventDefault();
if (isSafeishURL(url)) {
shell.openExternal(url);
}
});
@greggman在https://electronjs.org/docs/api/session#sessetpermissionrequesthandlerhandler 中查看开放的外部权限类型
你可以屏蔽那些👍
嗨,我正在使用 vue.js 并解决了受上述讨论启发的这个问题,如果像我这样使用 vue 的人也有同样的问题,我将我的代码粘贴在这里。
<template>
<div class="board-item" v-for="element in list" :key="element.id">
<span><a class='board-item-a' :href='element.url' target='_blank'>{{element.title}}</a></span>
</div>
</template>
<script>
mounted () {
this.$el.querySelectorAll('.board-item-a').forEach(a => {
a.addEventListener('click', (e) => {
e.preventDefault()
require('electron').shell.openExternal(e.target.href)
})
})
},
</script>
基于@alangrainger - ts 版本的评论:
const {app, shell, BrowserWindow} = require('electron');
...
mainWindow.webContents.on('new-window', function(event, url){
event.preventDefault();
shell.openExternal(url);
});
数据 URL 呢?
Angular 7 版本(实时重新加载):
const openExternalLinksInOSBrowser = (event, url) => {
if (url.match(/.*localhost.*/gi) === null && (url.startsWith('http:') || url.startsWith('https:'))) {
event.preventDefault();
shell.openExternal(url);
}
};
win.webContents.on('new-window', openExternalLinksInOSBrowser);
win.webContents.on('will-navigate', openExternalLinksInOSBrowser);
url.match(/.*localhost.*/gi) === null
部分是必需的,否则当您在 angular 应用程序中更改某些内容时,它会在您的操作系统浏览器中打开新窗口/选项卡,而不是在电子应用程序中重新加载它。
所有方法都可以正常工作,但仅适用于非 root 电子应用程序,我可以使用什么在 root 提升进程的默认操作系统浏览器上打开外部 url?
只是想为其他 Vue.js 用户发布答案。
<template>
<div>
<a href="https://google.com" target="_blank" @click.prevent="openExternalBrowser">Google.com Status</a>
</div>
</template>
<script>
const { remote } = require('electron');
export default {
name: 'HelloWorld',
methods: {
openExternalBrowser(e) {
remote.shell.openExternal(e.target.href);
},
},
};
</script>
只是想为其他 Vue.js 用户发布答案。
<template> <div> <a href="https://google.com" target="_blank" @click.prevent="openExternalBrowser">Google.com Status</a> </div> </template> <script> const { remote } = require('electron'); export default { name: 'HelloWorld', methods: { openExternalBrowser(e) { remote.shell.openExternal(e.target.href); }, }, }; </script>
谢谢你。
main.js
:app.on('web-contents-created', (e, contents) => {
contents.on('new-window', (e, url) => {
e.preventDefault();
require('open')(url);
});
contents.on('will-navigate', (e, url) => {
if (url !== contents.getURL()) e.preventDefault(), require('open')(url);
});
});
npm i open --save
只是想为其他 Vue.js 用户发布答案。
@travis5491811这会打开另一个带有正确页面的电子窗口。 这是预期的行为吗?
不,如果正确实施,我的帖子应该回答线程票“如何从默认操作系统浏览器打开 url 我提供的答案在我的应用程序 Electron v5.0.11
、Vue v2.6.10
中有效,在多台 Windows 10 和 Linux 桌面机器上进行了生产测试
只是想为其他 Vue.js 用户发布答案。
@travis5491811这会打开另一个带有正确页面的电子窗口。 这是预期的行为吗?
最有用的评论
我在 SO 上找到了这个代码片段:
将它放在我的主索引文件中,据我所知,它似乎可以正常工作,即使对于动态生成的链接也是如此。 我对电子太菜了,不知道这是否有任何我应该注意的缺点。 想法?