前端-通过自定义协议URI Scheme,点击Chrome中的链接打开IE

有部分老Web系统只有在IE下才能正常打开。其中有一部分是即使polyfill也没法搞定的兼容性原因,另一部分就是因为使用到了ActiveX。后者中我接触到的就有金格控件和泛微OA的。
对于新开发的Portal系统,没有余力为了迁就IE,对每个功能还额外做兼容性测试。于是剩下的方案就是在单点登录跳转到相应的页面的时候,指定使用IE打开。
其实这个功能并不罕见。比如腾讯的网站上经常有点击图标打开QQ,而淘宝网页上也有很多点击打开阿里旺旺。从原理上,这是利用到了Windows自定义协议URI Scheme。

URI Scheme

自定义协议从本质上就是修改注册表。官方资料可以参考这篇Registering an Application to a URI Scheme (Windows) | Microsoft Docs
官方给了一个范例,注册一个alert://的协议,点击后打开自定义的alert.exe。

1
2
3
4
5
6
7
8
9
10
HKEY_CLASSES_ROOT
alert
(Default) = "URL:Alert Protocol"
URL Protocol = ""
DefaultIcon
(Default) = "alert.exe,1"
shell
open
command
(Default) = "C:\Program Files\Alert\alert.exe" "%1"

方案1

能看出这是一种比较通用的方案。能打开自定义的alert.exe,自然也能打开IE。所以只要将以下内容保存为test.reg,点击运行后就能将注册表项导入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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"

与微软官方范例的差别在于将协议改为了openIE://(这个不重要),以及最后的命令改为了一串很长的:

1
cmd /c set m=%1 & call set m=%%m:openIE:=%% & call \"C:\\Program Files\\Internet Explorer\\iexplore.exe\" %%m%% & exit

/c参数表示执行完命令后关闭窗口。所以运行的时候你会看到先弹出一个命令行窗口。该命令接收了openIE://后的参数,然后传递给IE浏览器。

对应的超链接HTML如下:

1
<a href="openIE:www.baidu.com">网络联通性测试</a>

方案1的问题

除了会弹出一个命令行窗口的问题之外,还有一个比较严重的问题:无法正确处理特殊字符&。
比如url是https://www.baidu.com?key1=value&key2=value,那么第二个参数就会丢失。有些文章提出用^&替代&可以转义,实测无效。而大部分的单点登录URL后都是跟着一串参数。所以该方案无效。

方案2

方案2做了两个改动。一个是将改动从HKEY_CLASSES_ROOT改到了HKEY_CURRENT_USER\Software\Classes下。我理解影响范围会小一些。
另一个改动是在cmd参数里将也用引号包起来,并用反斜杠转义。
修改后的注册表导入内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\ie]
"URL Protocol"=""
@="URL:IE Protocol"

[HKEY_CURRENT_USER\Software\Classes\ie\shell]

[HKEY_CURRENT_USER\Software\Classes\ie\shell\open]

[HKEY_CURRENT_USER\Software\Classes\ie\shell\open\command]
@="cmd /c set url=\"%1\" & call set url=%%url:ie:=%% & call start iexplore -nosessionmerging -noframemerging %%url%%"

对应的HTML超链接如下:

1
<a href="ie:https://www.baidu.com?key1=value&key2=value2">网络联通性测试</a>

事实证明方案2可以正确处理URL参数。

最后提一下,标题中的Chrome只是指代我们常用的浏览器。并不表示Firefox或那一坨国产浏览器(恕不列举)就不能打开了。

参考资料

方案2的来源
windows - Registry - How to register Internet Explorer as a URI scheme and call from chrome? - Super User

方案1的来源
使用自定义协议实现Chrome打开IE_木子网

本文永久链接 [ https://galaxyyao.github.io/2019/07/11/前端-通过自定义协议URI-Scheme-点击Chrome中的链接打开IE/ ]