【问题标题】:how to communicate with a desktop application from browser?如何从浏览器与桌面应用程序通信?
【发布时间】:2012-01-24 15:46:21
【问题描述】:

是否可以通过浏览器与桌面应用程序通信?

我想做这样的事情,

假设我的 Web 应用程序中有一个按钮,其中包含指向数据源的 URL,当单击按钮时,桌面应用程序将打开并获取该数据源 URL 并使用桌面应用程序处理数据。

做这样的事情难吗?有什么例子吗?

【问题讨论】:

    标签: javascript browser


    【解决方案1】:

    在 Windows 上创建一个可通过

    调用的 custom URL Protocol 很简单

    <a href="whatever://somedata">..</a>

    这在 IE、FF 和 Chrome 中有效,但在后者中,链接必须通过 javascript 打开以避免全栏混淆。

    【讨论】:

    • MAC 和 Linux 上的任何等效项?
    • 这真的是一种通信方式还是桌面应用程序可以通过某种方式返回数据?
    【解决方案2】:

    您需要在桌面上运行一些东西,比如服务器,然后向它发出请求,让服务器打开一个应用程序。您可以使用 Node.js 来完成。当然,这需要服务器在客户端的桌面上运行。

    另一种方法是制作浏览器扩展程序/插件,并让人们安装它。这些扩展可能可能在桌面上启动应用程序。

    【讨论】:

    • 感谢我在codeproject.com/Articles/36517/…找到类似的信息
    • 它应该带有警告:从安全 POV 来看,运行本地服务器不是一个好主意。如果没有正确编组,它是获得系统特权的一个很大的攻击向量。其他网站也可以打开相同的应用程序,可能在您不知情的情况下。
    【解决方案3】:

    您可以轻松地将 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);
    }
    

    【讨论】:

      【解决方案4】:

      这是一个笨拙的建议,但我认为值得一提的是所有选项,因为自定义 URI 和正在运行的服务器解决方案非常复杂...生成一个包含感兴趣参数的小文件,并带有与您的桌面应用关联的自定义扩展名.因此,当用户单击浏览器按钮时,他们将不得不通过浏览器的文件下载对话框/工具栏,并且可能会出现一些烦人的安全验证弹出窗口......不是理想的用户体验,但可能是实现此类通信的最简单方法,并且不需要像服务器一样在后台运行的进程。

      我在公司内部使用了一个网络应用程序,用于连接旧数据库和组织不良的文件。我需要一种允许用户从网络打开实际文件而不是下载副本的方法,以便可以就地编辑它们。考虑这样的解决方案或自定义 URI 方案,以便可以简单地将文件名传递给不在后台运行的小型可执行文件并直接为用户打开。

      【讨论】:

        【解决方案5】:

        嗯,您需要类似客户端-服务器应用程序。服务器是一个轻量级的 http 服务器,它正在等待来自客户端(浏览器)的消息。例如,浏览器可以通过 ajax 与您的服务器通信。

        【讨论】:

          【解决方案6】:

          桌面应用程序应该在其中嵌入一个小型服务器,例如 Jetty。由于浏览器内容源域(例如 www.myDomain.com)与 Jetty 的 localhost 域不同,您会遇到安全问题。这些应该通过使用新标准 CORS(跨源资源共享)来克服。使用 CORS,Jetty 服务器告诉浏览器,如果请求来自源域 www.myDomain.com,它/localhost 允许跨域访问其资源。出于安全原因,我还会让 Jetty 拒绝任何源 ip 不是 localhost 的请求

          【讨论】:

          • 你有这样的例子吗?
          • 这不是一个好主意,请在接受的答案中查看我的评论。
          • @PnotNP 在您的其他评论中您提到其他应用程序也可以打开通信。但是 CORS 不是完全禁止这样做吗?
          • @Rainer 你试过这种方法吗?这甚至行得通吗?假设您以某种方式完成了这项工作,它也会向您“钓鱼”的网站开放。 CORS 不会阻止任何网络钓鱼网站以与合法网站相同的方式设置域访问权限。
          • @PnotNP 我正在实施这个 atm。我的服务器是通过 httpS 连接的,该地址将在 CORS-Config 中。只要用户不允许无效的 ssl 证书(在我的情况下由于缺乏特权,他不能),那应该可以防止钓鱼。顺便说一句很酷的名字;-)
          【解决方案7】:

          除了 Alex K 对 windows 的回答...对于那些在 macOS 和 Linux 上寻找解决方案的人。

          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

          macOS

          只需在您的应用程序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>
          

          【讨论】:

            猜你喜欢
            • 2012-02-01
            • 2016-08-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-30
            • 1970-01-01
            • 2012-06-22
            • 1970-01-01
            相关资源
            最近更新 更多