【发布时间】:2012-01-24 15:46:21
【问题描述】:
是否可以通过浏览器与桌面应用程序通信?
我想做这样的事情,
假设我的 Web 应用程序中有一个按钮,其中包含指向数据源的 URL,当单击按钮时,桌面应用程序将打开并获取该数据源 URL 并使用桌面应用程序处理数据。
做这样的事情难吗?有什么例子吗?
【问题讨论】:
标签: javascript browser
是否可以通过浏览器与桌面应用程序通信?
我想做这样的事情,
假设我的 Web 应用程序中有一个按钮,其中包含指向数据源的 URL,当单击按钮时,桌面应用程序将打开并获取该数据源 URL 并使用桌面应用程序处理数据。
做这样的事情难吗?有什么例子吗?
【问题讨论】:
标签: javascript browser
在 Windows 上创建一个可通过
调用的 custom URL Protocol 很简单<a href="whatever://somedata">..</a>
这在 IE、FF 和 Chrome 中有效,但在后者中,链接必须通过 javascript 打开以避免全栏混淆。
【讨论】:
您需要在桌面上运行一些东西,比如服务器,然后向它发出请求,让服务器打开一个应用程序。您可以使用 Node.js 来完成。当然,这需要服务器在客户端的桌面上运行。
另一种方法是制作浏览器扩展程序/插件,并让人们安装它。这些扩展可能可能在桌面上启动应用程序。
【讨论】:
您可以轻松地将 Fleck WebSocket 服务器添加到您的桌面应用程序,然后使用 Websocket 访问它。
注意:只有 Windows 8 和 10 通过 Microsoft 的 WebSockets 实现支持 WebSockets,但 Fleck 将适用于 Windows 7。
https://github.com/statianzo/Fleck 使用 NuGet 包管理器很容易将 Fleck 添加到您的项目中:
Install-Package Fleck
这是来自 Fleck 网页的 echo 示例(将其添加到 C# 程序以在启动期间执行):
var server = new WebSocketServer("ws://127.0.0.1:8181");
server.Start(socket =>
{
socket.OnOpen = () => Console.WriteLine("Open!");
socket.OnClose = () => Console.WriteLine("Close!");
socket.OnMessage = message => socket.Send(message);
});
在javascript中:
var exampleSocket = new WebSocket("ws://127.0.0.1:8181", "protocolOne");
exampleSocket.send("Here's some text that the server is urgently awaiting!");
//and receive (make a listener for the socket) :
exampleSocket.onmessage = function (event) {
console.log(event.data);
}
【讨论】:
这是一个笨拙的建议,但我认为值得一提的是所有选项,因为自定义 URI 和正在运行的服务器解决方案非常复杂...生成一个包含感兴趣参数的小文件,并带有与您的桌面应用关联的自定义扩展名.因此,当用户单击浏览器按钮时,他们将不得不通过浏览器的文件下载对话框/工具栏,并且可能会出现一些烦人的安全验证弹出窗口......不是理想的用户体验,但可能是实现此类通信的最简单方法,并且不需要像服务器一样在后台运行的进程。
我在公司内部使用了一个网络应用程序,用于连接旧数据库和组织不良的文件。我需要一种允许用户从网络打开实际文件而不是下载副本的方法,以便可以就地编辑它们。考虑这样的解决方案或自定义 URI 方案,以便可以简单地将文件名传递给不在后台运行的小型可执行文件并直接为用户打开。
【讨论】:
嗯,您需要类似客户端-服务器应用程序。服务器是一个轻量级的 http 服务器,它正在等待来自客户端(浏览器)的消息。例如,浏览器可以通过 ajax 与您的服务器通信。
【讨论】:
桌面应用程序应该在其中嵌入一个小型服务器,例如 Jetty。由于浏览器内容源域(例如 www.myDomain.com)与 Jetty 的 localhost 域不同,您会遇到安全问题。这些应该通过使用新标准 CORS(跨源资源共享)来克服。使用 CORS,Jetty 服务器告诉浏览器,如果请求来自源域 www.myDomain.com,它/localhost 允许跨域访问其资源。出于安全原因,我还会让 Jetty 拒绝任何源 ip 不是 localhost 的请求
【讨论】:
除了 Alex K 对 windows 的回答...对于那些在 macOS 和 Linux 上寻找解决方案的人。
大多数现代发行版都实现了 freedesktop 标准,其中之一是 desktop files。您可以使用[service] 创建桌面文件 部分。
$ cat test.desktop
[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Comment=My test app
Name=TestApp
Icon=TestIcon
Exec=/opt/test/test.sh %u
DBusActivatable=true
Categories=Network;
MimeType=x-scheme-handler/test; <------ This is handler for test://somedata URLs
NoDisplay=false
将此文件复制到/usr/share/applications/test.desktop
只需在您的应用程序Info.plist 文件中添加类似以下内容
<array>
<dict>
<key>CFBundleTypeIconFile</key>
<string>/tmp/test.png</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLName</key>
<string>com.mytest</string>
<key>CFBundleURLSchemes</key>
<array>
<string>test</string> <---- This is handler for test://somedata URLs hit on browser
</array>
</dict>
</array>
【讨论】: