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') λ₯Ό λͺ¨λ‘ μ‹œλ„ν–ˆκ³  λ‘˜ λ‹€ λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ›Ή μ‚¬μ΄νŠΈλ₯Ό μ—΄μ—ˆμŠ΅λ‹ˆλ‹€.

λ‚΄κ°€ μ‚¬μš©ν•˜λŠ” κ²°κ΅­ 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 을 μ‚¬μš©ν•˜κΈ°λ‘œ κ²°μ •ν–ˆμŠ΅λ‹ˆλ‹€. νƒˆμΆœ 등을 μ—‰λ§μœΌλ‘œ λ§Œλ“€κ³  싢지 μ•Šλ‹€λ©΄ μ‹œλ„ν•΄μ•Όν•©λ‹ˆλ‹€.

μ—¬λŸ¬λΆ„, ν•˜μ§€λ§Œ κ·€ν•˜μ˜ μ†”λ£¨μ…˜μ€ ν›Œλ₯­ν•˜μ§€λ§Œ " http://someurl.com "κ³Ό 같은 URL을 μ—¬λŠ” 방법을 κ°€λ‘œμ±„μ„œ shell.openExternal 둜 μ—¬λŠ” 방법이 κΆκΈˆν•©λ‹ˆλ‹€. μ„œλΉ„μŠ€ μ›Œμ»€λŠ” λ™μΌν•œ 도메인에 μžˆλŠ” νŒŒμΌμ— λŒ€ν•œ μš”μ²­λ§Œ μž‘μ„ 수 μžˆμŠ΅λ‹ˆλ‹€. 이것을 ν•  수 μžˆλŠ” λŠ₯λ ₯이 μžˆμŠ΅λ‹ˆκΉŒ? /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 슀폰 = 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>

@alangrainer - 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 뢀뢄이 ν•„μš”ν•©λ‹ˆλ‹€. 그렇지 μ•ŠμœΌλ©΄ 각도 μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œ 무언가λ₯Ό λ³€κ²½ν•  λ•Œ μ „μž μ•±μ—μ„œ λ‹€μ‹œ λ‘œλ“œν•˜λŠ” λŒ€μ‹  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을 μ—¬λŠ” 방법"μ΄λΌλŠ” μŠ€λ ˆλ“œ 티켓에 응닡해야 λ‚΄κ°€ μ œκ³΅ν•œ 닡변은 λ‚΄ μ•± Electron v5.0.11 , Vue v2.6.10 μ—μ„œ μž‘λ™ν•˜λ©° μ—¬λŸ¬ Windows 10 및 Linux λ°μŠ€ν¬ν†± μ»΄ν“¨ν„°μ—μ„œ ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œ ν…ŒμŠ€νŠΈλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λ‹€λ₯Έ Vue.js μ‚¬μš©μžλ₯Ό μœ„ν•œ 닡변을 κ²Œμ‹œν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

@travis5491811 그러면 μ˜¬λ°”λ₯Έ νŽ˜μ΄μ§€κ°€ μžˆλŠ” 또 λ‹€λ₯Έ Electron 창이 μ—΄λ¦½λ‹ˆλ‹€. 이것이 μ˜ˆμƒλœ λ™μž‘μž…λ‹ˆκΉŒ?

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰