替代自定义协议(URI 方案)

Posted

技术标签:

【中文标题】替代自定义协议(URI 方案)【英文标题】:Alternative to custom protocols (URI schemes) 【发布时间】:2020-02-09 10:18:17 【问题描述】:

我一直在我们所有的内部应用程序上广泛使用自定义协议来打开任何类型的文档(CAD、CAM、PDF 等),打开文件资源管理器并选择特定文件,以及运行其他应用程序。

几年前,我定义了一个myprotocol 协议,它执行C:\Windows\System32\wscript.exe,传递我的VBScript 名称和每个请求的任何参数。传递给脚本的第一个参数描述动作的类型(OpenDocumentShowFileInFileExplorerExportBOM 等),以下参数传递给动作。

直到去年,当wscript.exe 停止工作时,一切都运行良好(有关详细信息,请参阅here)。我通过将其复制到wscript2.exe 来解决该问题。创建副本现在是我们所有计算机标准配置中的一个步骤,使用wscript2.exe 现在是我们自定义协议的官方配置。 (我们的防病毒客户支持找不到与wscript.exe 交互的任何内容。

今天,在组装了一台新电脑后,我们发现:

Firefox 看不到wscript2.exe。如果我单击自定义协议链接,然后单击浏览按钮并打开文件夹,我只看到一小部分 .exe 文件,其中包括 wscript.exe,但不包括 wscript2.exe(我没有不知道这个问题是最近才出现的,因为我个人不使用 FireFox)。 Firefox 看到 wscript.exe,但仍然无法正常工作(与我之前链接的上一篇文章中描述的行为相同) Chrome 可与wscript2.exe 配合使用,但现在它总是要求确认。根据this article 的说法,这似乎是一种新方法,并且很快就会再次发生变化。每次点击确认框对我的用户来说都是一个很大的禁忌。这会减慢许多需要快速单击页面上数百个链接的工作流程,例如,查看 CAD 应用程序缩放到大型绘图中的一个几何图形。

我去年已经解决了一个问题,现在我正在处理另一个问题,阅读那篇文章让我感到害怕,让我认为很快就会出现更多问题。

那么问题来了:有没有使用自定义协议的替代方案?

我不是在开发供公众使用的网络应用程序。我的自定义协议需要 VBScript 文件、脚本使用的应用程序和大量网络共享文件夹。它们仅在我们的内部网络中使用,并且使用它们的计算机是手动配置的。

【问题讨论】:

【参考方案1】:

首先,即使只在内部网络上,这也是非常危险的。除非计算机/用户/浏览器被锁定在互联网之外,否则有人可能会猜到或发现您的协议名称,将链接发送给您公司中的某人并造成很多麻烦(也可能造成损失)。

无论如何...

由于您要控制所有计算机上的软件,您可以在每台计算机上添加一个小型服务器,只监听 localhost,它只是调用您的脚本。然后定义像 secret.myprotocol 这样的主机指向该服务器,例如 localhost:1234。

为了稍微减少潜在问题,本地服务器将仅使用 HTTPS,并使用适当的证书,HSTS 和 HPKP 设置为很长时间(由于您控制软件,因此您可以在需要时刷新它们)。最后两个,以防万一有人尝试设置相同的域,并且无论出于何种原因,主机覆盖不起作用并且用户最终调用了敌对服务器。

因此,链接必须从 myprotocol://whatever 更改为 https://secret.myprotocol/whatever

它确实引入了新的攻击面(“迷你服务器”),但应该很容易实现,以最小化该面的大小:)。 “迷你服务器”甚至不必是真正的 www 服务器,一个可以侦听套接字并调用 wscript.exe 的简单脚本就可以了(除非您需要向它传递更多信息)。 真实服务器有更多可能有错误的代码,但也允许添加更多内容,例如“通过”页面,显示信息“在 3 秒内打开文档 X...”和“取消”按钮。 它还可能需要某种会话登录(只是为了确保请求操作的是用户,而不是其他)。

【讨论】:

我不明白这对在客户端机器上运行有什么帮助。 每台机器上都会安装这样的“迷你服务器”。该服务器会根据浏览器的请求调用wscript.exe。因此,它可以作为一种从浏览器向wscript.exe 传递请求的代理。 我不想在我的答案中强制使用任何语言/框架,但是用 node.js、python 或类似语言编写这样的“迷你服务器”会很容易。甚至只是作为概念验证,稍后将被小型独立可执行文件取代:)。 你能确认我明白吗?今天的设置:添加xxx.vbs,将wscript.exe复制到wscript2.exe,添加协议到注册表。新设置:安装 python,添加 miniserver.py,在启动时执行 miniserver.py。较新的设置可能:使用 py2exe 并避免安装 python。我可以使用localhost:4567而不是配置子域吗? 是的新设置,但恐怕需要自定义域/子域。至少对于 Chrome。来自example.com 页面的链接在指向127.0.0.1 时被阻止,并且当它指向localhost 时需要用户确认(与自定义协议相同)。但我猜它不一定是公共的域/子域。您可以通过 Windows 上的“主机”文件添加“虚拟”域(但我使用 Windows 已经有几年了,所以最好先检查一下。我发现了这个:***.com/questions/42636711/…)。【参考方案2】:

blog post 的标题说明了一切:浏览器架构:Web 到应用程序通信概述

它描述了 Web 到应用通信技术的列表以及其中一些技术的专用帖子的链接。

列表中的第一个是应用程序协议,我已经使用了多年,但在去年左右开始崩溃(因此我提出了问题)。

第五个是Local Web Server,也就是ahwayakchih所描述的那个。

更新 (此更新遵循上述博客文章中的update)

显然我不是唯一一个认为这种行为变化是回归的人,因此发布了一个解决方法:旧行为(显示一个复选框允许记住答案)可以通过将这些键添加到注册表来恢复:

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Chromium]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001

【讨论】:

以上是关于替代自定义协议(URI 方案)的主要内容,如果未能解决你的问题,请参考以下文章

android webview与js简单的交互方案

如何在 C# 中调用自定义 url 协议?

Android自定义用户协议的解决方案

Android自定义用户协议的解决方案

Javascript URI 解析介绍

为通过 API 创建的 PayPal 账单协议设置自定义值