当WebSockets可用时,为什么要使用AJAX?


203

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

但是,自启动项目以来,我已经阅读了安全漏洞,并且一些浏览器默认选择禁用WebSocket。

这使我想到了一个问题:

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


2
以下是支持Web套接字的引擎列表。en.wikipedia.org/wiki/…– 2012
但丁

Answers:


209

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

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

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

如果您不需要WebSockets提供的特定好处,那么最好坚持使用AJAX和Comet等现有技术,因为这可以让您重新使用并与庞大的现有工具,技术,安全机制生态系统集成,知识库(例如,与WebSockets相比,stackoverflow上的更多的人知道HTTP / Ajax / Comet)等。

另一方面,如果创建的新应用程序在HTTP / Ajax / Comet的延迟和连接限制内不能很好地工作,则可以考虑使用WebSockets。

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

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


37
现在,在2014年初,WebSockets实际上是一个标准(RFC 6455),只有Opera mini不支持它。
德克·贝斯特2014年

4
的确,Opera Mini不支持它,但更令人尴尬的是缺乏对Android浏览器的支持,这使得与基于Webview的应用程序一起使用会变得更加复杂(Cordova PhoneGap)
Miles

2
@kanaka,如果两个文件都能很好地处理大文件,那为什么不简单地通过websocket发送所有文件呢?当可以通过WebSocket发送所有内容时,为什么还要烦扰页面/数据?(让我们假设它已经是2020年,并且所有浏览器都支持WebSockets)
Pacerier 2014年

3
@Pacerier一个完整的答案将是漫长的,但是基本上可以归结为您试图重新实现浏览器已经运行良好的功能(缓存,安全性,并行性,错误处理等)的事实。关于性能,尽管从头开始大文件传输的速度差不多,但是浏览器已经花了很多年时间来微调Web内容的缓存(其中大部分适用于AJAX请求),因此实际上,从AJAX切换到WebSockets不太可能提供很多现有功能的好处。但是对于低延迟的双向通信而言,这是一个巨大的胜利。
kanaka 2014年

5
对不起,但对我来说,它不能回答问题。基本上,这只是说它们并不是要相互替代,并且不完全支持WS(现在是)。它没有回答为什么您比Websocket更喜欢AJAX?让我们以不和谐为例。Discord使用WS将消息和事件从服务器推送到客户端,同时使用HTTP请求从客户端将消息发送到服务器(发送消息,请求数据等)。我来到这个问题上实际上是得到了为什么要这么做的答案。是否出于某种技术原因将AJAX置于开放式WS连接之上?
夏洛特·杜诺瓦

63

快进到2017年12月,每个浏览器都(实际上)支持Websocket,并且使用非常普遍。

但是,这并不意味着Websockets至少在某种程度上不能完全取代AJAX,尤其是在HTTP / 2适应性正在上升的时候。

简短的答案是,即使使用Websocket,AJAX对于大多数REST应用程序仍然非常有用。但是细节在于上帝,所以...:

AJAX轮询?

使用AJAX进行轮询(或长期轮询)正在逐渐消失(应该如此),但由于两个充分的理由(主要是用于较小的Web应用程序),仍继续使用AJAX

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

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

但是,Websocket推送远远优于AJAX(不需要重新验证或重新发送标头,不需要“无数据”往返等)。这是讨论了很多次。

用于REST的AJAX?

REST API调用是AJAX的更好用法。这种用法简化了代码库,并阻止了Websocket连接的阻塞(尤其是在中型数据上载时)。

有很多令人信服的理由都倾向于使用AJAX进行REST API调用和数据上传:

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

  2. 无论是在客户端还是在后端,使用AJAX进行的REST调用和上载都非常容易编码。

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

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

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

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

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

通过对上传碎片逻辑进行编码,可以轻松地恢复中断的上传(最困难的部分是对事物进行编码)。

HTTP / 2推送呢?

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

之前已经在此处进行了讨论,但是只需提及一个HTTP / 2连接即可为整个浏览器(所有标签页/窗口)提供服务,因此HTTP / 2推送的数据不知道它属于哪个标签页/窗口,消除了取代Websocket将数据直接推送到特定浏览器选项卡/窗口的功能。

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

和安全性?

好吧,通常,向程序员提供的信任和控制越多,工具的功能就越强大……并且涉及的安全性问题也就越多。

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

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

就我个人而言,如果我认为Websocket的状况略有改善,尤其是在您知道自己在做什么的时候,我认为这并没有太大的区别。

我的拙见

恕我直言,除了REST API调用外,我将使用Websockets进行所有操作。大数据上传我会分段并在可能的情况下通过Websocket发送。

恕我直言,应该禁止轮询,网络通信的成本令人震惊,即使对于新开发人员,Websocket推送也很容易管理。


2
小语法错误“如果我有事...”认为😀–
spottedmahn

2
@spottedmahn-谢谢!我想就是这样,我使用代码编辑器起草了文本st
Myst

1
抱歉,悬赏期满后我不在。我的计划不力。我设置了另一个赏金,将在23小时到期后奖励给您。
Duncan Jones

@Myst感谢您的出色解释。对于像fb / stackoverflow这样的实时通知,您希望使用什么?我正在为我的Web应用程序设计RestFull Web服务,但是非常困惑我应该使用什么通知功能?AJAX或WebSockets?
TheCoder

@puspen通知(IMHO)非常适合Websockets。在设计重新连接逻辑和脱机通知队列时,需要做出很多决定,但是实际的通知既易于编写,又可以通过websockets实现。
Myst

18

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

随着时间的流逝,WebSockets将受到越来越多的支持,但是与此同时,您应该始终具有基于HTTP的后备方法,用于将数据发送到浏览器。


幸运的是,大多数WebSocket框架都支持上述回退,包括将Flash用于套接字。Socketn.IO和SignalR都是不错的框架...虽然您确实受到限制,但是由于代理和负载平衡器的原因,您已经提到过。幸运的是,Node.JS和下一个IIS都在此角色上做得很好。
Tracker1 2012年

好奇:哪些运营商在端口80上阻止了WebSocket?哪个块可在端口443上保护WebSocket(WSS)?后者意味着强制的,透明的MITM Web代理..在公共网络中(只有公司网络)从未见过这种情况,因为它需要在浏览器中安装新的CA证书。
oberstet 2012年

举例来说,目前,Vodafone Italy在端口80上阻止了WS,但在端口443上允许了WSS。您可以通过我们的主页非常轻松地测试任何运营商,您可以通过HTTP和HTTPS对其进行访问。它尝试使用WebSockets,如果被阻止,则退回到HTTP。使用此URL在中间显示一个小部件,以报告当前的传输情况:lightstreamer.com/?s
Alessandro Alinone 2012年

17

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


11

WebSockets在较旧的Web浏览器中不起作用,并且支持 WebSocket的浏览器通常具有不同的实现。这几乎就是为什么一直没有使用它们代替AJAX的唯一很好的理由。


8
更好的原因是AJAX请求是普通的HTTP请求,这意味着它可以检索HTTP资源。WebSockets无法做到这一点。
Dan D.

@Dan例如,如果图像文件作为base64发送,CSS作为文本发送,JavaScript也作为文本发送,然后附加到文档,该怎么办?这看起来合理吗?
2012年

@丹 +1,我同意,我想我从问题的示例中快速流式传输数据的角度来解决这个问题,但这是正确的。
jli 2012年

@Dan D-有时您不希望所有这些废话,例如cookie和标头...
vsync

8
@ DanD。,HTTP和WebSocket是两个不同的协议,当然,由于我们不能使用HTTP协议请求WebSocket资源的原因,我们不能使用WebSocket协议请求HTTP资源!这并不意味着客户端无法请求通过Websocket协议发送的html和/或图像文件。
Pacerier,2014年

2

我认为我们无法对Websockets和HTTP进行清晰的比较,因为它们既不是竞争对手,也不能解决相同的问题。

Websocket是用于以近实时方式处理长期存在的双向数据流的绝佳选择,而REST非常适合偶尔进行的通信。使用websocket是一项可观的投资,因此对于偶尔的连接来说是一个过大的杀伤力。

您可能会发现,当存在高负载时,Websockets会做得更好,在某些情况下,HTTP会稍快一些,因为它可以利用缓存。将REST与Websockets进行比较就像将苹果与桔子进行比较。

我们应该检查哪种解决方案为我们的应用程序提供了更好的解决方案,哪种解决方案最适合我们的使用案例。


1
这个问题是关于AJAX的,而不是REST。的确,AJAX可用于REST,但也可用于轮询和长轮询。尽管我同意您的结论(可以从我的回答中看出),但我认为您的回答可以反映出这种区别(请注意,Websockets也可以用于REST,尽管不能使用HTTP方法)。
Myst

@Myst我同意你的看法。
Gaurav Gandhi

1

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.