【问题标题】:Why use AJAX when WebSockets is available?为什么在 WebSockets 可用时使用 AJAX?
【发布时间】:2012-05-09 18:44:26
【问题描述】:

我已经使用 WebSockets 有一段时间了,我选择使用 Node 服务器和 WebSockets 为我在大学的最后一年项目创建一个敏捷项目管理工具。我发现使用 WebSockets 使我的应用程序每秒可以处理的请求数量增加了 624%。

然而,自从开始这个项目以来,我已经了解到安全漏洞,并且一些浏览器选择默认禁用 WebSockets..

这引出了我的问题:

当 WebSockets 似乎在降低延迟和资源开销方面做得如此出色时,为什么还要使用 AJAX,AJAX 有什么比 WebSockets 做得更好的吗?

【问题讨论】:

标签: ajax node.js performance websocket


【解决方案1】:

WebSockets 在较旧的网络浏览器中不起作用,the ones that do support it 通常有不同的实现。这几乎是为什么它们没有一直被用来代替 AJAX 的唯一充分理由。

【讨论】:

  • 一个更好的理由是 AJAX 请求是一个普通的 HTTP 请求,这意味着它可以检索 HTTP 资源; WebSockets 做不到。
  • @Dan 例如,如果图像文件以 base64 格式发送,CSS 作为文本发送,JavaScript 也作为文本发送,然后附加到文档中怎么办?这有道理吗?
  • @DanD。 +1,我同意,我想我更多是从问题示例中的快速流数据的上下文中解决这个问题,但这绝对是正确的。
  • @Dan D - 有时您不希望所有的废话都越界,例如 cookie 和标头...
  • @DanD.,HTTP 和 WebSocket 是两个不同的协议,当然我们不能使用 WebSocket 协议请求 HTTP 资源,同样的原因我们不能使用 HTTP 协议请求 WebSocket 资源! 这并不意味着客户端不能请求通过 Websocket 协议发送的 html 和/或图像文件。
【解决方案2】:

除了旧浏览器的问题(包括 IE9,因为从 IE10 开始将支持 WebSockets),尚不支持 WebSockets 的网络中介仍然存在很大问题,包括透明代理、反向代理和负载平衡器。 有一些移动运营商完全阻断了 WebSocket 流量(即在 HTTP UPGRADE 命令之后)。

随着岁月的流逝,WebSockets 将得到越来越多的支持,但与此同时,您应该始终拥有一种基于 HTTP 的备用方法来向浏览器发送数据。

【讨论】:

  • 幸运的是,大多数 WebSocket 框架都支持上述后备方案,包括使用 Flash 作为套接字。 Socketn.IO 和 SignalR 都是不错的框架......虽然你真的很有限,正如你提到的,因为代理和负载平衡器。幸运的是,Node.JS 和下一个 IIS 在这个角色上也做得很好。
  • 好奇:哪些运营商在端口 80 上阻止了 WebSocket?哪个块在端口 443 上保护 WebSocket (WSS)?后者意味着强制、透明的 MITM 网络代理.. 在公共网络(仅限公司网络)中从未见过,因为它需要在浏览器中安装新的 CA 证书。
  • 例如,目前,意大利沃达丰在 80 端口阻止 WS,但在 443 端口允许 WSS。您可以通过我们的主页轻松测试任何运营商,您可以通过 HTTP 和 HTTPS 访问.它会尝试 WebSockets 并在它们被阻止时回退到 HTTP。使用此 URL 在中间显示一个报告当前传输的小部件:lightstreamer.com/?s
【解决方案3】:

WebSockets 并非旨在取代 AJAX,严格来说甚至不能替代 Comet/long-poll(尽管在很多情况下这是有意义的)。

WebSockets 的目的是在浏览器和服务器之间提供低延迟、双向、全双工和长时间运行的连接。 WebSockets 为浏览器应用程序开辟了新的应用程序域,这些应用程序使用 HTTP 和 AJAX(交互式游戏、动态媒体流、桥接现有网络协议等)是不可能实现的。

但是,WebSockets 和 AJAX/Comet 之间的目的肯定有重叠。例如,当浏览器想要收到服务器事件的通知(即推送)时,Comet 技术和 WebSockets 无疑都是可行的选择。如果您的应用程序需要低延迟推送事件,那么这将是支持 WebSockets 的一个因素。另一方面,如果您需要与现有框架和部署的技术(OAuth、RESTful API、代理、负载平衡器)共存,那么这将是支持 Comet 技术的一个因素(目前)。

如果您不需要 WebSockets 提供的特定好处,那么坚持使用 AJAX 和 Comet 等现有技术可能是一个更好的主意,因为这允许您重用并与现有的庞大工具、技术生态系统集成、安全机制、知识库(即 stackoverflow 上知道 HTTP/Ajax/Comet 的人比 WebSockets 多得多)等。

另一方面,如果您要创建的新应用程序在 HTTP/Ajax/Comet 的延迟和连接限制下无法正常工作,那么请考虑使用 WebSockets。

此外,一些答案表明 WebSockets 的缺点之一是有限/混合的服务器和浏览器支持。让我稍微分散一下。虽然 iOS(iPhone、iPad)仍然支持旧协议 (Hixie),但大多数 WebSockets 服务器同时支持 Hixie 和 HyBi/IETF 6455 版本。大多数其他平台(如果它们还没有内置支持)可以通过web-socket-js(基于 Flash 的 polyfill)获得 WebSockets 支持。这涵盖了绝大多数网络用户。此外,如果您使用 Node 作为服务器后端,则考虑使用 Socket.IO,其中包括 web-socket-js 作为后备,如果即使它不可用(或禁用),那么它将回退到使用任何 Comet 技术可用于给定的浏览器。

更新:iOS 6 现在支持当前的 HyBi/IETF 6455 标准。

【讨论】:

  • 现在在 2014 年初,WebSockets 实际上是一个标准(RFC 6455),只有 Opera mini 不支持它。
  • 没错,Opera Mini 不支持它,但更尴尬的是缺乏对 Android 浏览器的支持,这使得与基于 webview 的应用程序 (Cordova PhoneGap) 一起使用有点复杂
  • @kanaka,如果他们都同样擅长处理大文件,那么为什么不简单地通过 websockets 发送所有内容呢?当一切都可以通过 WebSockets 发送时,为什么还要打扰 ajaxing 页面/数据? (假设已经是 2020 年了,所有浏览器都支持 WebSockets)
  • @Pacerier 一个完整的答案会很长,但它基本上归结为您正在尝试重新实现浏览器已经做得很好的事情(缓存、安全性、并行性、错误处理,等等)。关于性能,虽然从头开始的原始大文件传输速度相似,但浏览器多年来一直在微调 Web 内容的缓存(其中大部分适用于 AJAX 请求),因此在实践中,从 AJAX 切换到 WebSockets 不太可能提供太多现有功能的好处。但对于低延迟的双向通信来说,这是一个巨大的胜利。
  • 我很抱歉,但对我来说它没有回答这个问题。它基本上只是说它们不打算相互替换,并且不完全支持 WS(现在支持)。它没有回答为什么您更喜欢 AJAX 而不是 websocket?让我们以不和谐为例。 Discord 使用 WS 将消息和事件从服务器推送到客户端,同时它使用 HTTP 请求从客户端到服务器(发送消息、请求数据等)。我来到这个问题实际上是为了回答你为什么要这样做。您将 AJAX 置于开放 WS 连接之上是否有某种技术原因?
【解决方案4】:

我读到的关于 websockets 和安全性的大部分抱怨来自 web 浏览器安全和防火墙安全工具的安全供应商。问题是他们不知道如何对 websockets 流量进行安全分析,因为一旦它完成了从 HTTP 到 websocket 二进制协议的升级,数据包内容及其含义是特定于应用程序的(基于您编写的任何程序)。对于这些以分析和分类所有互联网流量为生的公司来说,这显然是一场后勤噩梦。 :)

【讨论】:

    【解决方案5】:

    快进到 2017 年 12 月,Websockets are supported by (practically) every browser,它们的使用非常普遍。

    然而,这并不意味着 Websockets 成功地取代了 AJAX,至少不是完全取代,尤其是在 HTTP/2 适配正在兴起的情况下。

    简短的回答是,即使在使用 Websockets 时,AJAX 仍然适用于大多数 REST 应用程序。但是上帝在细节中,所以...:

    AJAX 轮询?

    The use of AJAX for polling (or long polling) is dying out(应该是),但它仍然在使用有两个很好的原因(主要用于较小的网络应用程序):

    1. 对于许多开发人员来说,AJAX 更容易编码,尤其是在编码和设计后端时。

    2. 使用 HTTP/2,与 AJAX(建立新连接)相关的最高成本被消除,使 AJAX 调用具有相当高的性能,尤其是在发布和上传数据时。

    但是,Websocket push is far superior to AJAX(无需重新验证或重新发送标头,无需“无数据”往返等)。这was discussed 多次。

    用于 REST 的 AJAX?

    AJAX 更好的用途是 REST API 调用。这种使用简化了代码库并防止了 Websocket 连接阻塞(尤其是在中等大小的数据上传时)。

    有多个compelling reasons to prefer AJAX for REST API calls和数据上传:

    1. AJAX API 实际上是为 REST API 调用而设计的,非常适合。

    2. 使用 AJAX 的 REST 调用和上传代码更容易在客户端和后端编写代码。

    3. 随着数据负载的增加,Websocket 连接可能会被阻塞,除非对消息分段/多路复用逻辑进行编码。

      如果在单个 Websocket send 调用中执行上传,它可能会阻塞 Websocket 流,直到上传完成。这会降低性能,尤其是在速度较慢的客户端上。

    一种常见的设计使用通过 Websocket 传输的小型双向消息,而 REST 和数据上传(客户端到服务器)利用 AJAX 的易用性来防止 Websocket 阻塞。

    但是,在较大的项目中,Websockets 提供的灵活性以及代码复杂性和资源管理之间的平衡将使平衡倾向于 Websockets。

    例如,基于 Websocket 的上传可以提供在连接断开并重新建立后恢复大型上传的能力(还记得您要上传的 5GB 电影吗?)。

    通过编码上传碎片逻辑,很容易恢复中断的上传(困难的部分是编码)。

    HTTP/2 推送怎么样?

    我可能应该补充一点,HTTP/2 推送功能不会(也可能不能)取代 Websockets。

    这在之前是discussed here,但足以说明单个 HTTP/2 连接服务于整个浏览器(所有选项卡/窗口),因此 HTTP/2 推送的数据不知道哪个选项卡/窗口它属于,消除了它取代 Websocket 将数据直接推送到特定浏览器选项卡/窗口的能力。

    虽然 Websocket 非常适合小型双向数据通信,但 AJAX 仍然具有许多优势 - 尤其是在考虑更大的有效负载(上传等)时。

    还有安全性?

    嗯,一般来说,向程序员提供的信任和控制越多,工具就越强大......并且会出现更多的安全问题。

    AJAX 本质上会占上风,因为它的安全性内置于浏览器的代码中(这有时是有问题的,但它仍然存在)。

    另一方面,AJAX 调用更容易受到“中间人”攻击,而 Websockets 安全问题通常是应用程序代码中引入安全漏洞的错误(通常后端身份验证逻辑是您可以找到这些漏洞的地方) )。

    我个人认为这并没有太大的不同,如果有的话,我认为 Websockets 稍微好一点,尤其是当你知道自己在做什么的时候。

    我的拙见

    恕我直言,除了 REST API 调用,我会使用 Websockets。大数据上传我会尽可能分片并通过 Websockets 发送。

    恕我直言,轮询应该被取缔,网络流量的成本是可怕的,而且即使对于新开发人员来说,Websocket 推送也很容易管理。

    【讨论】:

    • 小语法错误“如果我有什么事情……”想想?
    • @spottedmahn - 谢谢!我想这就是我使用代码编辑器起草文本的原因?
    • 抱歉,赏金到期时我不在。我的计划很糟糕。我已经设置了另一个赏金,我会在 23 小时后奖励给你。
    • @Myst 感谢您的精彩解释。对于像 fb/stackoverflow 这样的实时通知,您更喜欢什么?我正在为我的 Web 应用程序设计一个 RestFull Web 服务,但是很困惑我应该使用什么来实现通知功能? AJAX 还是 WebSockets?
    • @puspen 通知(恕我直言)非常适合 Websockets。在设计重新连接逻辑和离线通知队列时,需要做出很多决定,但实际通知既易于编码,又可以使用 websockets 执行。
    【解决方案6】:

    我认为我们无法对 Websockets 和 HTTP 做一个明确的比较,因为它们既不是竞争对手,也解决不了同样的问题。

    Websocket 是近乎实时地处理长期双向数据流的绝佳选择,而 REST 则非常适合偶尔进行通信。使用 websockets 是一项相当大的投资,因此对于偶尔的连接来说它是一种过度杀伤力。

    您可能会发现 Websocket 在高负载时表现更好,在某些情况下 HTTP 会稍微快一些,因为它可以利用缓存。比较 REST 和 Websockets 就像比较苹果和橘子。

    我们应该检查哪一个为我们的应用程序提供更好的解决方案,哪一个最适合我们的用例胜出。

    【讨论】:

    • 问题一般是关于 AJAX,而不是 REST。 AJAX 确实可以用于 REST,但它也可以用于轮询和长轮询。尽管我同意您的结论(从我的回答中可以看出),但我认为您的回答可以反映出区别(请注意,Websockets 也可以用于 REST,尽管不能使用 HTTP 方法)。
    • @Myst 我同意你的看法。
    【解决方案7】:

    HTTP 和 Websockets 之间差异的示例,以客户端大小的库的形式可以处理 Websocket 端点(如 REST API)和 RESTful 端点(如客户端上的 Websockets)。 https://github.com/mikedeshazer/sockrest 此外,对于那些试图在客户端上使用 websocket API 的人来说,反之亦然。 libs/sockrest.js 几乎清楚地说明了差异(或者说应该)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 2020-08-21
      • 2021-12-24
      • 2019-04-10
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      相关资源
      最近更新 更多