Electron: <a>デフォルトのOSブラウザ</a>からURLを開くにはどうすればよい

作成日 2015年04月01日  ·  26コメント  ·  ソース: electron/electron

最も参考になるコメント

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

メインのインデックスファイルにドロップしましたが、動的に生成されたリンクであっても、私が知る限り機能しているようです。 私は電子に精通しすぎて、これに注意すべき欠点があるかどうかを知ることができません。 考え?

全てのコメント26件

私のセットアップでは、 shell.openExternal('http://example.com')shell.openItem('http://example.com')両方を試し、両方ともバックグラウンドでWebサイトを開きました。

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 」のようなURLを開いてから、 shell.openExternal開く試みを傍受する方法を考えていますか? Service Workerでは、同じドメイン上のファイルへのリクエストのみをキャッチできます。 これを行う能力はありますか? / cc @maxogden @AlicanC

ここで@havenchykと同じ質問ですが、デフォルトで外部のリンクを開くように電子に指示する方法はありますか?

アプリが1つのウィンドウのみを使用し、アプリ内のすべての外部リンクが新しいウィンドウで開くことを保証できる場合(たとえば、 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); });

次に、ブラウザで開きたい各要素に「open-in-browser」クラスをドロップする必要があります。

これは、他の誰かがJQueryを探している場合に備えて、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);
  }
});

@greggmanhttps://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のコメントに

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アプリケーションで何かを変更すると、electronアプリでリロードする代わりに、OSブラウザーで新しいウィンドウ/タブが開くためです。

すべての方法は正常に機能しますが、ルート以外の電子アプリでのみ機能します。ルート昇格されたプロセスのデフォルトのOSブラウザーで外部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ウィンドウが開きます。 これは予想される動作ですか?

いいえ、適切に実装された場合、私の投稿はスレッドチケット「デフォルトのOSブラウザでURLを開くにはどうすればよいですか」に答えるはず私が提供した答えは、複数のWindows10およびLinuxデスクトップマシンで本番環境でテストされた私のアプリElectron v5.0.11 、Vue v2.6.10で機能します

他のVue.jsユーザーに回答を投稿したかっただけです。

@ travis5491811これにより、右側のページで別のElectronウィンドウが開きます。 これは予想される動作ですか?

このページは役に立ちましたか?
0 / 5 - 0 評価