自定义URL Protocol 协议实现跨浏览器打开链接

因历史原因,在chrome或firefox下打开IE这种跨浏览器打开链接也是一种需求,有两种方式可以实现,一是注册自定义协议(Registering an Custom Protocal)实现,二是通过桌面服务间接操作

注册自定义协议实现

自定义协议简单讲就是你经常看到的
<a href=”tencent://message …,
还有
– thunder://  迅雷的
– item:// itunes的
– ed2k:// 电驴

同样我们可以使用<a href=”openIE:https://bing.com”>使用IE浏览器打开bing</a>或 <a href=”openCHROME:https://bing.com”>使用CHROME浏览器打开bing</a>

如何注册自定义协议可以参考 Registering an Application to a URI Scheme

注册一个openIE和openCHROME,可以看这个注册表文件custom_protocol_reg ,双击安装.reg注册表文件就可以实现。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\openIE]
@="URL:OpenIE Protocol"  
"URL Protocol"=""
  
[HKEY_CLASSES_ROOT\openIE\DefaultIcon]  
@="iexplore.exe,1"  
  
[HKEY_CLASSES_ROOT\openIE\shell]  
  
[HKEY_CLASSES_ROOT\openIE\shell\open]  
  
[HKEY_CLASSES_ROOT\openIE\shell\open\command]
#@="cmd /c set m=%1 & call set m=%%m:openie:=%% & call \"C:\\Program Files\\Internet Explorer\\iexplore.exe\" %%m%% & exit" 
@="C:\\Program Files\\Internet Explorer\\iexplore.exe \"http://mb.com/redirect.html?%1\""

[HKEY_CLASSES_ROOT\openCHROME]
@="URL:OpenCHROME Protocol"
"URL Protocol"=""
  
[HKEY_CLASSES_ROOT\openCHROME\DefaultIcon]  
@="chrome.exe,1"  
  
[HKEY_CLASSES_ROOT\openCHROME\shell]  
  
[HKEY_CLASSES_ROOT\openCHROME\shell\open]  
  
[HKEY_CLASSES_ROOT\openCHROME\shell\open\command]  
@="cmd /c set m=%1 & call set m=%%m:openCHROME:=%% & call \"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" %%m%% & exit"
<a href="openIE:http://www.bing.com" onclick="checkCustomProtocol(this)">Open bing.com with IE</a><br>
<a href="openCHROME:http://www.bing.com" onclick="checkCustomProtocol(this)">Open bing.com with Chrome</a><br>
<a href="undefined:http://www.bing.com" onclick="checkCustomProtocol(this)">Open bing.com with Undefined Protocal</a><br>
<p><a href="javascript:download('custom_protocol.reg')">Download and install custom_protocol.reg</a></p><a id="download" download="custom_protocol.reg" style="height:0"></a>
<script>
function checkCustomProtocol(_target) {
    var timeout
    if(!_target.href.startsWith('http')) {
        timeout = setTimeout(function () {
            alert(" protocol is not register, please install the .reg file") 
        }, 1000)
        window.addEventListener('blur', function() { clearTimeout(timeout) })
    }
}
function download(_file) {
  var downloadlink = document.querySelector("#download")
  var rawFile = new XMLHttpRequest()
  rawFile.open("GET", _file , true)
  rawFile.onreadystatechange = function() {
      if(rawFile.readyState === 4) {
          var data = encodeURIComponent(rawFile.responseText) // https://stackoverflow.com/questions/49372533/javascript-export-text-file-not-recognizing-r-n-in-firefox
          downloadlink.setAttribute("href", "data:text/reg;charset=UTF-8,"+data) // text/plain 会被firefox 51转成.reg.txt文件
          downloadlink.click()
      }
  }
  rawFile.send()
}

</script>

IE浏览器的一些参数参考: https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/hh826025(v=vs.85)

通过桌面服务间接操作

现代浏览器中的JavaScript程序没有权限去调用系统资源,但桌面程序可以。那么只需这个桌面程序能提供HTTP或websocket服务,接受AJAX指令,就可以帮助JavaScript间接调用系统资源.

server.py
...
if program == 'ie':
    os.system('"C:\Program Files\internet explorer\iexplore.exe" ' + url)
elif program == 'chrome':
    os.system('"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" ' + url)
...
server_socket.bind(("", 8000))
...

JS只需将指令传过去

<a onclick="openPage('http://127.0.0.1/index.html','chrome')">用Chrome打开此链接</a>
...
<script>
    function openPage(_url, _program) {
        var x = document.createElement("script");
        x.src='http://127.0.0.1:8000/?url='+_url+'&program='+_program;
        document.body.appendChild(x)
    }
</script>
这个还需要考虑安全问题。

Leave a Reply

Your email address will not be published. Required fields are marked *