Electron: Bagaimana cara membuka url dari <a>browser OS default?</a>

Dibuat pada 1 Apr 2015  ·  26Komentar  ·  Sumber: electron/electron

Komentar yang paling membantu

Saya menemukan cuplikan kode ini di 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);
    });

Menjatuhkannya di file indeks utama saya, tampaknya berfungsi sejauh yang saya tahu, bahkan untuk tautan yang dibuat secara dinamis. Saya terlalu noob di elektron untuk mengetahui apakah ada kekurangan untuk ini yang harus saya waspadai. Pikiran?

Semua 26 komentar

Pada pengaturan saya, saya mencoba shell.openExternal('http://example.com') dan shell.openItem('http://example.com') dan keduanya membuka situs web di latar belakang.

Saya akhirnya menggunakan child_process.execSync('start http://example.com') di Win32 dan child_process.execSync('open http://example.com') di Darwin sehingga browser benar-benar muncul dan mendapatkan fokus.

Di Linux, Anda dapat menggunakan xdg-open:
child_process.execSync('xdg-open http://example.com')

Saya sebenarnya telah memutuskan untuk menggunakan node-open . Anda harus mencobanya jika Anda tidak ingin dipusingkan dengan melarikan diri dan semacamnya.

Teman-teman, tetapi solusi Anda bagus, tetapi saya bertanya-tanya bagaimana cara mencegat upaya membuka url seperti " http://someurl.com " dan kemudian membuka dengan shell.openExternal ? Pekerja layanan memungkinkan untuk menangkap hanya permintaan ke file di domain yang sama. Apakah ada kemampuan untuk melakukan ini? /cc @maxogden @AlicanC

Pertanyaan yang sama di sini dengan @havenchyk , apakah ada cara untuk memberi tahu elektron untuk membuka tautan eksternal secara default?

Jika aplikasi Anda hanya menggunakan satu jendela, dan Anda dapat menjamin bahwa setiap tautan eksternal di aplikasi Anda terbuka di jendela baru (melalui mis. target="_blank" ), Anda dapat melakukan sesuatu seperti:

webContents.on('new-window', function(event, url){
  event.preventDefault();
  open(url);
});

Di mana webContents adalah WebContents BrowserWindow utama Anda dan open adalah fungsi yang membuka url di browser Anda (saya menggunakan node-open seperti yang direkomendasikan oleh AlicanC).

Akan lebih baik jika ada peristiwa yang dipicu ketika tautan _any_ diklik, sehingga aplikasi dapat memutuskan apakah itu harus dibuka di browser, tetapi saya belum menemukan peristiwa seperti itu jika ada.

Saya menemukan cuplikan kode ini di 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);
    });

Menjatuhkannya di file indeks utama saya, tampaknya berfungsi sejauh yang saya tahu, bahkan untuk tautan yang dibuat secara dinamis. Saya terlalu noob di elektron untuk mengetahui apakah ada kekurangan untuk ini yang harus saya waspadai. Pikiran?

Saya menggunakan potongan kode ini:

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)

Pertama-tama nyatakan proses spawn

`app.controller('GuideCtrl', ['$scope', ($scope)=>{
const spawn = membutuhkan('child_process').spawn;

  $scope.openBrowser=(url)=>{
     let exec = spawn('explore', [url], {});
     exec.stdout.on('data', (data)=> {
        console.log('stdout: ' + data)
     });
  }

}])`

dan sebelum memanggil metode

<a ng-click="openBrowser('https://google.com')">Goto google</a>

Apakah shell.openExternal memiliki masalah keamanan? Misalnya jika tautan keluar dari jaringan maka data bersih mentah diteruskan ke shell.openExternal atau salah satu fungsi lain di atas. Apakah shell.openExternal memastikan tidak ada hal buruk yang akan terjadi? Apakah saya perlu memfilter skema?

Berdasarkan kode dari @rubencodes , saya menggunakan:

const shell = require('electron').shell; $('.open-in-browser').click((event) => { event.preventDefault(); shell.openExternal(event.target.href); });

Kemudian Anda hanya perlu menjatuhkan kelas 'buka-dalam-browser' ke setiap elemen yang ingin Anda buka di browser.

Inilah salah satu yang tidak memerlukan JQuery, kalau-kalau ada orang lain yang mencarinya. Ini akan secara otomatis membuka tautan apa pun yang dimulai dengan 'http' di browser eksternal.

Masukkan ini ke dalam proses penyaji Anda:

// 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)
  }
})

Jika Anda ingin SEMUA tag <a> terbuka di browser default, coba ini di main.ts Anda:

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

mainWin.webContents.on('will-navigate', (event, url) => {
  event.preventDefault()
  shell.openExternal(url)
});

Ini mengasumsikan Anda memiliki aplikasi satu halaman seperti saya. Jika tidak, Anda perlu melakukan sanitasi ekstra.

Saya hanya ingin menegaskan kembali bahwa menggunakan ini dengan konten pengguna tanpa daftar putih mungkin merupakan lubang keamanan yang menganga. Saya tidak tahu apa yang dilakukan oleh berbagai skema dan apa inputnya, tetapi hanya sebagai contoh sederhana tautan seperti ini

 <a href="imessage:hello">click me</a>

Akan meminta pengguna di Chrome dan Safari di macOS tetapi dengan kode di atas Electron hanya akan membuka aplikasi.

Hampir terasa seperti Electron itu sendiri harus default untuk menjadi lebih aman di sini daripada menyerahkannya kepada setiap programmer individu untuk mencari tahu bagaimana membuatnya aman sendiri.

Minimal Anda mungkin menginginkan sesuatu seperti

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 Lihat jenis izin eksternal terbuka di https://electronjs.org/docs/api/session#sessetpermissionrequesthandlerhandler

Anda dapat memblokirnya 👍

Hai, saya menggunakan vue.js dan menyelesaikan masalah ini yang terinspirasi oleh diskusi di atas, jika seseorang seperti saya yang menggunakan vue juga memiliki masalah yang sama, saya menempelkan kode saya di sini.

<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>

Berdasarkan komentar dari @alangrainger - versi ts:

const {app, shell, BrowserWindow} = require('electron');

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

Bagaimana dengan URL data?

Versi Angular 7 (dengan reload langsung):

        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);

Bagian url.match(/.*localhost.*/gi) === null diperlukan karena jika tidak, ketika Anda mengubah sesuatu di aplikasi sudut Anda, itu akan membuka jendela/tab baru di browser OS Anda alih-alih memuatnya kembali di aplikasi elektron.

Semua metode berfungsi dengan baik tetapi hanya pada aplikasi elektron non root, apa yang dapat saya gunakan untuk membuka url eksternal pada browser OS default pada proses root yang ditinggikan?

Hanya ingin memposting jawaban untuk pengguna Vue.js lainnya.

<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>

Hanya ingin memposting jawaban untuk pengguna Vue.js lainnya.

<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>

Terima kasih.

Pada 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);
    });
});

Anda perlu menginstal paket terbuka :

npm i open --save

Hanya ingin memposting jawaban untuk pengguna Vue.js lainnya.

@travis5491811 Ini membuka jendela Elektron lain dengan halaman kanan. Apakah ini perilaku yang diharapkan?

Tidak, ketika diterapkan dengan benar, posting saya harus menjawab tiket utas "Bagaimana cara membuka url dari browser OS default ", tetapi untuk pengguna vue .

Hanya ingin memposting jawaban untuk pengguna Vue.js lainnya.

@travis5491811 Ini membuka jendela Elektron lain dengan halaman kanan. Apakah ini perilaku yang diharapkan?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat