Warum AJAX verwenden, wenn WebSockets verfügbar ist?

203

Ich benutze WebSockets jetzt schon eine Weile. Ich habe mich entschieden, ein agiles Projektmanagement-Tool für mein Abschlussprojekt an der Universität zu erstellen, das Node Server und WebSockets verwendet. Ich stellte fest, dass die Verwendung von WebSockets die Anzahl der Anforderungen pro Sekunde, die meine Anwendung verarbeiten konnte, um 624% erhöhte.

Seit dem Start des Projekts habe ich jedoch Sicherheitslücken und einige Browser gelesen, die WebSockets standardmäßig deaktivieren.

Dies führt mich zu der Frage:

Warum AJAX verwenden, wenn WebSockets die Latenz und den Ressourcenaufwand so gut zu senken scheint? Gibt es etwas, das AJAX besser kann als WebSockets?

Jack
quelle
2
Hier ist eine Liste von Engines, die Web-Sockets unterstützen. en.wikipedia.org/wiki/…
Dante

Antworten:

209

WebSockets soll AJAX nicht ersetzen und ist nicht einmal ein Ersatz für Comet / Long-Poll (obwohl dies in vielen Fällen sinnvoll ist).

Der Zweck von WebSockets besteht darin, eine bidirektionale Vollduplex- und Langzeitverbindung mit geringer Latenz zwischen einem Browser und einem Server bereitzustellen. WebSockets öffnet neue Anwendungsdomänen für Browseranwendungen, die mit HTTP und AJAX nicht wirklich möglich waren (interaktive Spiele, dynamische Medienströme, Überbrückung mit vorhandenen Netzwerkprotokollen usw.).

Es gibt jedoch sicherlich eine Überschneidung zwischen WebSockets und AJAX / Comet. Wenn der Browser beispielsweise über Serverereignisse (z. B. Push) benachrichtigt werden möchte, sind Comet-Techniken und WebSockets sicherlich beide praktikable Optionen. Wenn Ihre Anwendung Push-Ereignisse mit geringer Latenz benötigt, ist dies ein Faktor zugunsten von WebSockets. Wenn Sie jedoch mit vorhandenen Frameworks und bereitgestellten Technologien (OAuth, RESTful-APIs, Proxys, Load Balancer) koexistieren müssen, ist dies (vorerst) ein Faktor zugunsten der Comet-Techniken.

Wenn Sie die spezifischen Vorteile von WebSockets nicht benötigen, ist es wahrscheinlich besser, sich an vorhandene Techniken wie AJAX und Comet zu halten, da Sie so ein riesiges vorhandenes Ökosystem aus Tools, Technologien und Sicherheitsmechanismen wiederverwenden und integrieren können , Wissensdatenbanken (dh weit mehr Leute im Stackoverflow kennen HTTP / Ajax / Comet als WebSockets) usw.

Wenn Sie jedoch eine neue Anwendung erstellen, die innerhalb der Latenz- und Verbindungsbeschränkungen von HTTP / Ajax / Comet nicht gut funktioniert, sollten Sie die Verwendung von WebSockets in Betracht ziehen.

Einige Antworten weisen auch darauf hin, dass einer der Nachteile von WebSockets die eingeschränkte / gemischte Server- und Browserunterstützung ist. Lassen Sie mich das nur ein wenig verbreiten. Während iOS (iPhone, iPad) weiterhin das ältere Protokoll (Hixie) unterstützt, unterstützen die meisten WebSockets-Server sowohl Hixie als auch die HyBi / IETF 6455- Version. Die meisten anderen Plattformen (sofern sie noch keine integrierte Unterstützung haben) können WebSockets-Unterstützung über Web-Socket-js (Flash-basierte Polyfüllung) erhalten. Dies gilt für die überwiegende Mehrheit der Webnutzer. Wenn Sie Node für das Server-Backend verwenden, sollten Sie Socket.IO verwenden, das Web-Socket-js als Fallback enthält. Wenn selbst das nicht verfügbar (oder deaktiviert) ist, wird auf die Verwendung der Comet-Technik zurückgegriffen verfügbar für den angegebenen Browser.

Update : iOS 6 unterstützt jetzt den aktuellen HyBi / IETF 6455-Standard.

Kanaka
quelle
37
Und jetzt, zu Beginn des Jahres 2014, ist WebSockets praktisch ein Standard (RFC 6455) und wird nur von Opera mini nicht unterstützt.
Dirk Bester
4
Es stimmt, Opera Mini unterstützt es nicht, aber peinlicher ist die mangelnde Unterstützung des Android-Browsers, was die Verwendung mit Webview-basierten Apps (Cordova PhoneGap) etwas komplexer macht
Miles M.
2
@kanaka, Wenn beide große Dateien gleich gut machen, warum dann nicht einfach alles über Websockets senden? Warum sich die Mühe machen, Seiten / Daten zu jaxen, wenn alles über WebSockets gesendet werden kann? (Nehmen wir an, es ist bereits 2020 und alle Browser unterstützen WebSockets)
Pacerier
3
@Pacerier Eine vollständige Antwort wäre lang, aber im Grunde läuft es darauf hinaus, dass Sie versuchen, Dinge neu zu implementieren, die der Browser bereits gut macht (Caching, Sicherheit, Parallelität, Fehlerbehandlung usw.). In Bezug auf die Leistung hatten Browser Jahre Zeit, um das Caching von Webinhalten (von denen ein Großteil für AJAX-Anforderungen gilt) zu optimieren, obwohl die Übertragungsgeschwindigkeit für große Dateien von Grund auf ähnlich wäre. In der Praxis ist es daher unwahrscheinlich, dass ein Wechsel von AJAX zu WebSockets viel bringt Nutzen für vorhandene Funktionalität. Für die bidirektionale Kommunikation mit geringer Latenz ist dies jedoch ein großer Gewinn.
Kanaka
5
Es tut mir leid, aber für mich beantwortet es die Frage nicht. Grundsätzlich heißt es nur, dass sie sich nicht gegenseitig ersetzen sollen und dass WS nicht vollständig unterstützt wird (es ist jetzt). Es antwortet nicht, warum Sie AJAX gegenüber Websocket bevorzugen würden? Nehmen wir zum Beispiel Discord. Discord verwendet WS, um Nachrichten und Ereignisse vom Server an Clients zu senden, während es HTTP-Anforderungen vom Client an den Server verwendet (Nachricht senden, Daten anfordern usw.). Ich bin zu dieser Frage gekommen, um tatsächlich eine Antwort zu bekommen, warum Sie das tun würden. Gibt es einen technischen Grund, warum Sie AJAX über die offene WS-Verbindung stellen würden?
Charlotte Dunois
63

Schneller Vorlauf bis Dezember 2017, Websockets werden von (praktisch) jedem Browser unterstützt und ihre Verwendung ist sehr verbreitet.

Dies bedeutet jedoch nicht, dass es Websockets gelungen ist, AJAX zu ersetzen, zumindest nicht vollständig, insbesondere da die HTTP / 2-Anpassung zunimmt.

Die kurze Antwort lautet, dass AJAX für die meisten REST-Anwendungen auch bei Verwendung von Websockets noch hervorragend geeignet ist. Aber Gott steckt im Detail, also ...:

AJAX zum Abrufen?

Die Verwendung von AJAX für Abfragen (oder lange Abfragen) stirbt aus (und sollte es auch sein), wird jedoch aus zwei guten Gründen weiterhin verwendet (hauptsächlich für kleinere Web-Apps):

  1. Für viele Entwickler ist AJAX einfacher zu codieren, insbesondere wenn es um das Codieren und Entwerfen des Backends geht.

  2. Mit HTTP / 2 wurden die höchsten Kosten im Zusammenhang mit AJAX (dem Aufbau einer neuen Verbindung) eliminiert, sodass AJAX-Anrufe sehr leistungsfähig sind, insbesondere beim Posten und Hochladen von Daten.

Allerdings ist Websocket Push weit überlegen AJAX (keine Notwendigkeit zur erneuten Authentifizierung oder resend Header, keine Notwendigkeit für „keine Daten“ Roundtrips, etc). Dies wurde mehrmals diskutiert .

AJAX für REST?

Eine bessere Verwendung für AJAX sind REST-API-Aufrufe. Diese Verwendung vereinfacht die Codebasis und verhindert, dass die Websocket-Verbindung blockiert wird (insbesondere bei mittelgroßen Daten-Uploads).

Es gibt eine Reihe zwingender Gründe, AJAX für REST-API-Aufrufe und Daten-Uploads zu bevorzugen :

  1. Die AJAX-API wurde praktisch für REST-API-Aufrufe entwickelt und passt hervorragend.

  2. REST-Aufrufe und Uploads mit AJAX lassen sich sowohl auf dem Client als auch im Backend erheblich einfacher codieren.

  3. Mit zunehmender Datennutzlast werden Websocket-Verbindungen möglicherweise blockiert, sofern die Nachrichtenfragmentierungs- / Multiplexlogik nicht codiert ist.

    Wenn ein Upload in einem einzelnen Websocket- sendAufruf ausgeführt wird, kann ein Websocket-Stream blockiert werden, bis der Upload abgeschlossen ist. Dies verringert die Leistung, insbesondere bei langsameren Clients.

Ein gängiges Design verwendet kleine Bidi-Nachrichten, die über Websockets übertragen werden, während REST- und Daten-Uploads (Client zu Server) die Benutzerfreundlichkeit von AJAX nutzen, um zu verhindern, dass das Websocket blockiert.

Bei größeren Projekten wird jedoch die Flexibilität von Websockets und das Gleichgewicht zwischen Codekomplexität und Ressourcenmanagement das Gleichgewicht zugunsten von Websockets beeinflussen.

Zum Beispiel könnten Websocket-basierte Uploads die Möglichkeit bieten, große Uploads fortzusetzen, nachdem eine Verbindung getrennt und wiederhergestellt wurde (erinnern Sie sich an den 5-GB-Film, den Sie hochladen wollten?).

Durch das Codieren der Upload-Fragmentierungslogik ist es einfach, einen unterbrochenen Upload fortzusetzen (der schwierige Teil war das Codieren des Dings).

Was ist mit HTTP / 2-Push?

Ich sollte wahrscheinlich hinzufügen, dass die HTTP / 2-Push-Funktion Websockets nicht ersetzt (und wahrscheinlich auch nicht ersetzen kann).

Dies wurde hier bereits erläutert , es genügt jedoch zu erwähnen, dass eine einzelne HTTP / 2-Verbindung den gesamten Browser (alle Registerkarten / Fenster) bedient, sodass Daten, die von HTTP / 2 übertragen werden, nicht wissen, zu welcher Registerkarte / welchem ​​Fenster sie gehören. Es entfällt die Fähigkeit, die Fähigkeit von Websocket zu ersetzen, Daten direkt auf eine bestimmte Registerkarte / ein bestimmtes Browserfenster zu übertragen.

Während Websockets für die kleine bidirektionale Datenkommunikation hervorragend geeignet sind, bietet AJAX dennoch eine Reihe von Vorteilen - insbesondere bei größeren Nutzdaten (Uploads usw.).

Und Sicherheit?

Je mehr Vertrauen und Kontrolle einem Programmierer geboten wird, desto leistungsfähiger ist das Tool ... und desto mehr Sicherheitsbedenken treten auf.

AJAX hätte von Natur aus die Oberhand, da seine Sicherheit in den Code des Browsers integriert ist (was manchmal fraglich ist, aber immer noch vorhanden ist).

Auf der anderen Seite sind AJAX-Aufrufe anfälliger für "Man in the Middle" -Angriffe, während Websockets-Sicherheitsprobleme normalerweise Fehler im Anwendungscode sind, die eine Sicherheitslücke verursacht haben (normalerweise finden Sie diese in der Backend-Authentifizierungslogik).

Persönlich finde ich das nicht so groß, wenn ich denke, dass Websockets etwas besser dran sind, besonders wenn Sie wissen, was Sie tun.

Meine bescheidene Meinung

IMHO würde ich Websockets für alles außer REST-API-Aufrufen verwenden. Big-Data-Uploads Ich würde fragmentieren und wenn möglich über Websockets senden.

Umfragen, IMHO, sollten verboten werden, die Kosten im Netzwerkverkehr sind schrecklich und Websocket Push ist selbst für neue Entwickler einfach zu verwalten.

Myst
quelle
2
Kleiner Grammatikfehler 'wenn überhaupt, was ich denke ...' denke spotted
Spottedmahn
2
@spottedmahn - Danke! Ich denke, das ist, was passiert, ich benutze meinen Code-Editor, um Text zu entwerfen
Myst
1
Entschuldigung, ich war abwesend, als das Kopfgeld abgelaufen war. Schlechte Planung meinerseits. Ich habe ein weiteres Kopfgeld festgelegt, das ich Ihnen nach Ablauf der 23 Stunden gewähren werde.
Duncan Jones
@Myst danke für diese tolle Erklärung. Was würden Sie für Live-Benachrichtigungen wie fb / stackoverflow bevorzugen? Ich entwerfe einen RestFull-Webservice für meine Webanwendung, bin aber sehr verwirrt, was ich für die Benachrichtigungsfunktion verwenden soll. AJAX oder WebSockets?
TheCoder
@ Pushpen-Benachrichtigungen eignen sich (IMHO) hervorragend für Websockets. Es sind viele Entscheidungen zu treffen, wenn Sie Wiederverbindungslogik und Offline-Benachrichtigungswarteschlangen entwerfen, aber die eigentliche Benachrichtigung ist sowohl einfach zu codieren als auch mit Websockets durchzuführen.
Myst
18

Zusätzlich zu Problemen mit älteren Browsern (einschließlich IE9, da WebSockets ab IE10 unterstützt werden) gibt es immer noch große Probleme mit Netzwerkintermediären, die WebSockets noch nicht unterstützen, einschließlich transparenter Proxys, Reverse-Proxys und Load Balancer. Es gibt einige Mobilfunkanbieter, die den WebSocket-Verkehr vollständig blockieren (dh nach dem Befehl HTTP UPGRADE).

Mit den Jahren werden WebSockets immer mehr unterstützt. In der Zwischenzeit sollten Sie jedoch immer über eine HTTP-basierte Fallback-Methode zum Senden von Daten an die Browser verfügen.

Alessandro Alinone
quelle
Glücklicherweise unterstützen die meisten WebSocket-Frameworks diese Fallbacks, einschließlich der Verwendung von Flash für Sockets. Socketn.IO und SignalR sind beide anständige Frameworks ... obwohl Sie wirklich eingeschränkt sind, wie Sie aufgrund von Proxys und Load Balancern erwähnen. Glücklicherweise leisten sowohl Node.JS als auch der nächste IIS mit dieser Rolle gute Arbeit.
Tracker1
Neugierig: Welche Carrier blockieren WebSocket an Port 80? Welches blocksichere WebSocket (WSS) an Port 443? Letzteres impliziert erzwungene, transparente MITM-Webproxys. Dies wurde in öffentlichen Netzwerken (nur in Unternehmensnetzwerken) nie gesehen, da neue CA-Zertifikate in Browsern installiert werden müssen.
Oberstet
Gegenwärtig blockiert Vodafone Italien derzeit WS auf Port 80, lässt jedoch WSS auf Port 443 zu. Sie können jeden Netzbetreiber ganz einfach über unsere Homepage testen, auf die Sie sowohl über HTTP als auch über HTTPS zugreifen können. Es versucht WebSockets und greift auf HTTP zurück, wenn sie blockiert sind. Verwenden Sie diese URL, um ein Widget in der Mitte anzuzeigen, das den aktuellen Transport meldet
Alessandro Alinone
17

Die meisten Beschwerden, die ich über Websockets und Sicherheit gelesen habe, stammen von Sicherheitsanbietern von Webbrowsersicherheits- und Firewall-Sicherheitstools. Das Problem ist, dass sie nicht wissen, wie eine Sicherheitsanalyse des Websockets-Datenverkehrs durchgeführt werden soll, da nach dem Upgrade von HTTP auf das Websocket-Binärprotokoll der Paketinhalt und seine Bedeutung anwendungsspezifisch sind (je nachdem, was Sie programmieren). Dies ist offensichtlich ein logistischer Albtraum für diese Unternehmen, deren Lebensunterhalt auf der Analyse und Klassifizierung Ihres gesamten Internetverkehrs beruht. :) :)

Tim Lovell-Smith
quelle
11

WebSockets funktionieren in älteren Webbrowsern nicht, und diejenigen, die dies unterstützen, haben häufig unterschiedliche Implementierungen. Das ist so ziemlich der einzige gute Grund, warum sie nicht immer anstelle von AJAX verwendet werden.

jli
quelle
8
Ein besserer Grund ist, dass eine AJAX-Anforderung eine normale HTTP-Anforderung ist, was bedeutet, dass sie HTTP-Ressourcen abrufen kann. WebSockets können das nicht.
Dan D.
@Dan Was ist, wenn beispielsweise Bilddateien als base64, CSS als Text, JavaScript auch als Text gesendet und dann an das Dokument angehängt werden? Wäre das plausibel?
Jack
@ DanD. +1, ich stimme zu, ich denke, ich näherte mich der Frage eher aus dem Kontext des schnellen Streaming von Daten als im Beispiel der Frage, aber das ist definitiv richtig.
jli
@ Dan D - manchmal möchten Sie nicht, dass all dieser Mist über die Linie geht, wie Cookies und Header ...
vsync
8
@DanD., HTTP und WebSocket sind zwei unterschiedliche Protokolle. Natürlich können wir keine HTTP-Ressourcen mit dem WebSocket-Protokoll anfordern, aus demselben Grund, aus dem wir keine WebSocket-Ressourcen mit dem HTTP-Protokoll anfordern können! Dies bedeutet nicht, dass der Client keine HTML- und / oder Bilddateien anfordern kann, die über das Websocket-Protokoll gesendet wurden.
Pacerier
2

Ich glaube nicht, dass wir Websockets und HTTP klar vergleichen können, da sie keine Rivalen sind und nicht die gleichen Probleme lösen.

Websockets sind eine gute Wahl, um langlebiges bidirektionales Daten-Streaming nahezu in Echtzeit zu verarbeiten, während REST für gelegentliche Kommunikation hervorragend geeignet ist. Die Verwendung von Websockets ist eine beträchtliche Investition und daher ein Overkill für gelegentliche Verbindungen.

Möglicherweise stellen Sie fest, dass Websockets bei hohen Lasten besser funktionieren. HTTP ist in einigen Fällen etwas schneller, da Caching verwendet werden kann. Der Vergleich von REST mit Websockets ist wie der Vergleich von Äpfeln mit Orangen.

Wir sollten prüfen, welche Lösung für unsere Anwendung besser ist und welche am besten zu unseren Anwendungsfallgewinnen passt.

Gaurav Gandhi
quelle
1
Die Frage betraf AJAX im Allgemeinen und nicht REST im Besonderen. Es ist wahr, dass AJAX für REST verwendet werden kann, aber es wird auch für Abfragen und Langzeitabfragen verwendet. Obwohl ich Ihrer Schlussfolgerung zustimme (wie Sie meiner Antwort entnehmen können), könnte Ihre Antwort die Unterscheidung widerspiegeln (beachten Sie, dass Websockets auch für REST verwendet werden können, jedoch nicht mithilfe von HTTP-Methoden).
Myst
@Myst Ich stimme dir zu.
Gaurav Gandhi
1

Ein Beispiel für die Unterschiede zwischen HTTP und Websockets in Form einer Bibliothek in Clientgröße, die Websocket-Endpunkte wie REST-APIs und RESTful-Endpunkte wie Websockets auf dem Client verarbeiten kann. https://github.com/mikedeshazer/sockrest Auch für diejenigen, die versuchen, eine Websocket-API auf dem Client zu verwenden oder umgekehrt, wie sie es gewohnt sind. Die libs / sockrest.js machen die Unterschiede ziemlich deutlich (oder sollen es eher).

Mike D.
quelle