网页如何向本地网络发送消息
Posted
技术标签:
【中文标题】网页如何向本地网络发送消息【英文标题】:How can a web page send a message to the local network 【发布时间】:2014-12-24 06:44:59 【问题描述】:我们的 Web 应用程序有一个按钮,它应该将数据发送到本地网络上的服务器,然后再在打印机上打印一些东西。
到目前为止,这很容易:该按钮使用令牌触发了对 http://printerserver/print.php
的 AJAX POST 请求,该页面连接到 Web 应用程序以验证令牌并获取要打印的数据,然后打印。
但是,我们现在通过 HTTPs 交付我们的 Web 应用程序(为此我宁愿不再使用 HTTP),并且较新版本的 Chrome 和 Firefox 不再向 HTTP 地址发出请求,它们不再甚至发送请求以检查 CORS 标头。
现在,跨协议 XHR 的现代替代方案是什么? Websockets 也有同样的问题吗? (谷歌搜索并没有弄清楚这里的当前状态。)我可以使用 TCP 套接字了吗?我也不想切换到 GET 请求,因为该操作不是幂等的,它可能对预加载和缓存有实际影响。
我可以以任何方式更改打印机服务器上的应用程序(所以我可以用 NodeJS 或其他东西替换它)但我不能更改用户的浏览器(信任 printerserver 的自签名证书例如)。
【问题讨论】:
只是一个想法,但您是否尝试过使用 CURL 来提出您的请求?因为 CURL 会创建自己的会话,所以它不应该受到浏览器行为方式的影响。 我认为从问题中可以清楚地看到:机器 printerserver 和用户的浏览器在一个网络中,Web 服务器在互联网上。 如果我理解正确,您正在尝试从 HTTPS 网站调用“printerserver/print.php”。尝试在 443 端口运行“printerserver/print.php”服务器 - 以支持 HTTPS,因此您的调用将使用相同的协议。 【参考方案1】:您可以将网络服务器上的打印请求存储在队列中,并让打印服务器定期轮询打印请求。
如果这不可能,我会在网络服务器和打印服务器网络之间建立一个隧道或 ***。这样您就可以从服务器端的网络服务器而不是客户端发出打印请求。如果您使用 curl,则有一些标志可以忽略无效的 SSL 证书等(我仍然怀疑引入队列会更好,因此打印请求不会阻塞)。
如果网络服务器可以通过 ssh 连接到打印服务器所在的网络上的某物,您可以执行以下操作:ssh params user@host 这里有一些 curl 命令。
我能想到的第三个选项,如果 printserver 可以绑定到例如 webserver 域的子域,例如:print.somedomain.com,你可以让它被 somedomain.com 证书信任,IIRC 你有从打印服务器证书创建 CSR(证书签名请求),并使用 somedomain.com 证书对其进行签名。也许它本身甚至不需要成为子域,但也许这是浏览器在客户端执行它的要求。
【讨论】:
我已经存储了这些请求,并且打印机服务器已经连接到网络服务器以获取其数据。我只需要一种让浏览器告诉打印机服务器执行此操作的方法,因此打印会在单击后几秒钟发生。你的最后一段似乎很有趣,但对我来说太模糊了。 打印服务器不能自己决定何时打印吗?如果您将需要完成的所有内容存储在网络服务器上,并且打印服务器每隔 X 秒检查一次网络服务器是否应该执行任何任务。打印完成后,它可以发送命令将其从网络服务器队列中删除。【参考方案2】: 托管 https webapp 的服务器可以反向代理打印服务器, 但由于打印机是用户本地的,这可能不起作用。打印服务器应该有正确的 CORS 标头
Access-Control-Allow-Origin: *
或:
Access-Control-Allow-Origin: https://www.example.com
但是there are pitfalls with using the wildcard.
【讨论】:
我不明白,你说的是服务器到服务器的通信吗?应用程序的网络服务器无法到达 printerserver 机器的地址。 您能否分享更多有关您的服务器(用于您的 web 应用程序)的信息?你能分享一下你有什么样的打印机/型号吗?可能还有其他解决方案可能不必处理 CORS。【参考方案3】:最简单的方法是向 webapp 添加一个路由,该路由仅将请求中继到打印服务器。因此,向https://myapp.com/print
发出您的 AJAX POST 请求,并为向http://printerserver/print.php
发出请求的服务器端代码提供动力,并使用它自己收到的完全相同的 POST 内容。正如@dnozay 所说,这通常称为reverse proxy。是的,要做到这一点,您必须重新配置您的打印服务器以接受来自网络服务器的(经过身份验证的)请求。
或者,您可以将打印服务器切换为 https 并直接从客户端调用它。
请注意,安全 (https) 页面 probably 上的不安全 (http) web-socket 连接也不会 work。并且有充分的理由:通常,通过在他们看来是安全的页面上建立不安全的连接来误导人们是一个坏主意。
【讨论】:
鉴于***.com/questions/26615508/…,我不明白这是怎么可能的【参考方案4】:根据我从问题中了解到的情况,无法从 Web 应用程序访问打印服务器,因此 反向代理解决方案在这里不起作用。
跨域策略限制您从浏览器向打印服务器发出请求。
如果希望通过 HTTPS 页面与打印服务器通信,您需要打印服务器也将 print.php 公开为 HTTPS。
您可以创建一个 DNS A 记录作为您的 Web 应用程序的子域,它解析为您的打印服务器的内部地址。
通过这些步骤,您应该能够更新您的打印服务器页面以响应浏览器应该尊重的许可 CORS 标头。我认为浏览器甚至不会在没有 TLD 的情况下跨不同的协议方案(HTTPS 与 HTTP)或向内部域发出 CORS 请求。
【讨论】:
以上是关于网页如何向本地网络发送消息的主要内容,如果未能解决你的问题,请参考以下文章