javascript 如何从浏览器与桌面应用程序通信?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8989693/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to communicate with a desktop application from browser?
提问by Gihan Lasita
Is it possible to communicate with a desktop application from browser?
是否可以从浏览器与桌面应用程序通信?
I want to do something like this,
我想做这样的事情,
Let's say there is a button in my web application with a URL to a data source and when button is clicked desktop application opens and get that data source URL and process data with desktop application.
假设我的 Web 应用程序中有一个带有数据源 URL 的按钮,单击按钮时桌面应用程序打开并获取该数据源 URL 并使用桌面应用程序处理数据。
Is it difficult to do such thing? Any examples?
做这样的事情难吗?有什么例子吗?
采纳答案by Alex Turpin
You will need to have something running on the deskop, like a server, and make a request to it for the server to open up an application. You could do it with a Node.js. Of course that requires the server to be running on the client's desktop.
你需要在桌面上运行一些东西,比如服务器,并向它发出请求,让服务器打开一个应用程序。你可以用 Node.js 来做。当然,这需要服务器在客户端的桌面上运行。
The alternative would be to make a browser extension / plugin, and have people install that. Those extensions could probablylaunch an application on the desktop.
另一种方法是制作浏览器扩展/插件,并让人们安装它。这些扩展可能会在桌面上启动应用程序。
回答by Alex K.
On windows its trivial to create a custom URL Protocolthat's invokable via
在 Windows 上,创建一个可通过以下方式调用的自定义 URL 协议是微不足道的
<a href="whatever://somedata">..</a>
<a href="whatever://somedata">..</a>
This works in IE, FF and Chrome, although in the latter the link must be opened via javascript to avoid omni-bar confusion.
这适用于 IE、FF 和 Chrome,但在后者中,必须通过 javascript 打开链接以避免omni-bar 混淆。
回答by codejitsu
Hm, you need something like client-server application. The server is a lightweight http server, which is waiting for messages from the client (browser). The browser can communicate with your server via ajax for example.
嗯,您需要类似客户端 - 服务器应用程序的东西。服务器是一个轻量级的 http 服务器,它正在等待来自客户端(浏览器)的消息。例如,浏览器可以通过 ajax 与您的服务器进行通信。
回答by robisrob
Here is a clunky suggestion, but I think worth mentioning all the options since the custom URI and running server solutions are pretty involved... Generate a small file containing the parameters of interest, with a custom extension associated with your desktop app. So when the user clicks the browser button they will have to go through the browser's file download dialog/toolbar and maybe some annoying security verification popups... not ideal user experience, but might be the easiest way to implement this type of communication, and doesn't require a process running in the background like a server.
这是一个笨拙的建议,但我认为值得一提的是所有选项,因为自定义 URI 和正在运行的服务器解决方案非常复杂……生成一个包含感兴趣参数的小文件,并带有与您的桌面应用程序相关联的自定义扩展名。因此,当用户单击浏览器按钮时,他们将不得不浏览浏览器的文件下载对话框/工具栏,并且可能会出现一些烦人的安全验证弹出窗口……不是理想的用户体验,但可能是实现此类通信的最简单方法,并且不需要像服务器一样在后台运行的进程。
I have a web app used within my company for interfacing to old databases and poorly organized files. I need a way to allow the users to open the actual files from the network and not download copies, so they can be edited in place. Considering a solution like this or the custom URI scheme so that a small executable not running in the background can simply be passed the filename and open it for the user directly.
我在公司内部使用了一个 Web 应用程序,用于连接旧数据库和组织不良的文件。我需要一种方法来允许用户从网络打开实际文件而不是下载副本,以便可以就地编辑它们。考虑这样的解决方案或自定义 URI 方案,以便一个不在后台运行的小型可执行文件可以简单地传递文件名并直接为用户打开它。
回答by inor
the desktop application should embed a small server in it, like Jetty. Since the browser content source domain (e.g. www.myDomain.com) is different than the localhost domain of the Jetty, you would run into security problems. These should be overcome by the use of CORS (Cross Origin Resource Sharing) which is a new standard. Using CORS, the Jetty server tells the browser that it/localhost allows Cross domain access to its resources if the requests originate from the source domain www.myDomain.com. For security reasons, i would also make the Jetty reject any request whose source ip is not localhost
桌面应用程序应该在其中嵌入一个小型服务器,例如 Jetty。由于浏览器内容源域(例如 www.myDomain.com)与 Jetty 的 localhost 域不同,您会遇到安全问题。这些应该通过使用 CORS(跨源资源共享)这一新标准来克服。使用 CORS,Jetty 服务器告诉浏览器,如果请求来自源域 www.myDomain.com,它/localhost 允许跨域访问其资源。出于安全原因,我还会让 Jetty 拒绝任何源 ip 不是 localhost 的请求
回答by inor
You can easily add Fleck WebSocket server to your desktop application, and then access this using Websocket.
您可以轻松地将 Fleck WebSocket 服务器添加到您的桌面应用程序,然后使用 Websocket 访问它。
Note: Only Windows 8 and 10 support WebSockets through Microsoft's WebSockets implementation, but Fleck will work with Windows 7.
注意:只有 Windows 8 和 10 通过 Microsoft 的 WebSockets 实现支持 WebSockets,但 Fleck 将适用于 Windows 7。
https://github.com/statianzo/FleckIt's quite easy to add Fleck to your project using NuGet Package Manager:
https://github.com/statianzo/Fleck使用 NuGet 包管理器将 Fleck 添加到您的项目非常容易:
Install-Package Fleck
Here is the echo example from Fleck webpage (add this to the C# program to execute during startup):
这是来自 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);
});
In the javascript:
在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);
}
回答by PnotNP
In addtion to Alex K's answer for windows... for those looking for solution on macOS and Linux.
除了 Alex K 对 windows 的回答之外……对于那些在 macOS 和 Linux 上寻找解决方案的人。
Linux
Linux
Most of the modern distros implement freedesktop standards and one of them is desktop files. You can create a desktop file with [service]section.
大多数现代发行版都实现了 freedesktop 标准,其中之一是桌面文件。您可以使用[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
Copy this file in /usr/share/applications/test.desktop
把这个文件复制进去 /usr/share/applications/test.desktop
macOS
苹果系统
Simply add something like following in your applications Info.plist
file
只需在您的应用程序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>