Документы @luicaps находятся здесь https://github.com/atom/atom-shell/blob/master/docs/api/shell.md#shellopenexternalurl
В своей настройке я попробовал как shell.openExternal('http://example.com')
и shell.openItem('http://example.com')
и оба открыли веб-сайт в фоновом режиме.
В итоге я использовал child_process.execSync('start http://example.com')
в Win32 и child_process.execSync('open http://example.com')
в Дарвине, так что браузер действительно всплывает и получает фокус.
В Linux вы можете использовать xdg-open:
child_process.execSync('xdg-open http://example.com')
Я действительно решил использовать node-open . Вы должны попробовать, если не хотите связываться с побегом и тому подобным.
Ребята, но у вас отличные решения, но мне интересно, как перехватить попытку открыть url типа « 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, а open
- это функция, которая открывает URL-адрес в вашем браузере (я использую node-open, как рекомендовано AlicanC).
Было бы неплохо, если бы при нажатии _любой_ ссылки происходило событие, чтобы приложение могло решить, должно ли оно открываться в браузере, но я не нашел такого события, если оно существует.
Я нашел этот фрагмент кода на 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
гарантирует, что ничего плохого не случится? Мне нужно фильтровать схемы?
Основываясь на коде из
const shell = require('electron').shell;
$('.open-in-browser').click((event) => {
event.preventDefault();
shell.openExternal(event.target.href);
});
Затем вам просто нужно добавить класс open-in-browser к каждому элементу, который вы хотите открыть в браузере.
Вот тот, который не требует 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>
Будет запрашивать пользователя в Chrome и Safari на macOS, но с указанным выше кодом 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, что я могу использовать, чтобы открыть внешний 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 Откроется еще одно окно Electron с правой страницей. Это ожидаемое поведение?
Нет, при правильной реализации мой пост должен отвечать на тикет потока «Как открыть URL-адрес из браузера ОС по vue
.
Просто хотел опубликовать ответ для других пользователей Vue.js.
@ travis5491811 Откроется еще одно окно Electron с правой страницей. Это ожидаемое поведение?
Самый полезный комментарий
Я нашел этот фрагмент кода на SO:
Бросил его в свой основной индексный файл, кажется, он работает, насколько я могу судить, даже для динамически генерируемых ссылок. Я слишком новичок в электронике, чтобы знать, есть ли у этого недостатки, которых я должен остерегаться. Мысли?