Wie sicher sind versteckte AJAX-Anforderungen, die eine gefälschte Leistung erbringen?

48

Was ist eine versteckte AJAX-Anfrage?

Ich habe eine Zunahme der Verwendung von versteckten AJAX-Anforderungen festgestellt, mit denen die Aktion eines Benutzers augenscheinlich sofort ausgeführt wird. Ich werde diese Art von AJAX-Anforderung als nicht blockierend bezeichnen. Es handelt sich um eine AJAX-Anforderung, ohne dass der Benutzer davon Kenntnis hat, dass sie ausgeführt wird, sie wird im Hintergrund ausgeführt und der Vorgang ist stumm ( es gibt keine ausführlichen Informationen zum erfolgreichen Abschluss des AJAX-Aufrufs ). Das Ziel ist es, die Operation so aussehen zu lassen, als sei sie sofort eingetreten, wenn sie wirklich nicht abgeschlossen ist.

Hier sind Beispiele für nicht blockierende AJAX-Anforderungen.

  • Benutzer klickt auf eine Sammlung von E-Mails löschen. Die Elemente verschwinden sofort aus ihrem Posteingang und können mit anderen Vorgängen fortfahren. Währenddessen verarbeitet eine AJAX-Anforderung das Löschen der Elemente im Hintergrund.
  • Der Benutzer füllt ein Formular für neue Datensätze aus. Klicken Sie auf Speichern. Das neue Element wird sofort in der Liste angezeigt. Der Benutzer kann weiterhin neue Datensätze hinzufügen.

Zur Verdeutlichung sind hier Beispiele für das Blockieren von AJAX-Anforderungen aufgeführt.

  • Der Benutzer klickt auf eine Sammlung von E-Mails, um sie zu löschen. Ein Sanduhr-Cursor erscheint. Die AJAX-Anfrage wird gestellt und wenn sie antwortet, wird der Sanduhr-Cursor ausgeschaltet. Der Benutzer muss eine Sekunde warten, bis der Vorgang abgeschlossen ist.
  • Der Benutzer füllt ein Formular für neue Datensätze aus. Klicken Sie auf Speichern. Das Formular wird grau, und ein AJAX-Loader wird animiert. Es wird die Meldung "Ihre Daten wurden gespeichert" angezeigt, und der neue Datensatz wird in der Liste angezeigt.

Der Unterschied zwischen den beiden obigen Szenarien besteht darin, dass ein nicht blockierendes AJAX-Setup keine Rückmeldung über eine Betriebsleistung liefert, und ein blockierendes AJAX-Setup dies tut.

Das Risiko versteckter AJAX-Anfragen

Das größte Risiko dieses AJAX-Anforderungsstils besteht darin, dass sich die Webanwendung in einem völlig anderen Zustand befindet, wenn die AJAX-Anforderung fehlschlägt.

Zum Beispiel ein nicht blockierendes Beispiel;

  • Der Benutzer wählt eine Reihe von E-Mails aus. Klicken Sie auf die Schaltfläche Löschen. Der Vorgang scheint sofort zu erfolgen (die Elemente verschwinden einfach aus der Liste). Der Benutzer klickt dann auf die Schaltfläche "Verfassen" und beginnt mit der Eingabe einer neuen E-Mail. Zu diesem Zeitpunkt entdeckt der JavaScript-Code, dass die AJAX-Anforderung fehlgeschlagen ist. Das Skript könnte eine Fehlermeldung anzeigen, aber es ist zu diesem Zeitpunkt wirklich sinnlos.

Alternativ ein Sperrbeispiel;

  • Der Benutzer wählt eine Reihe von E-Mails aus. Klicken Sie auf die Schaltfläche Löschen. Es wird eine Sanduhr angezeigt, aber der Vorgang schlägt fehl. Sie erhalten eine Fehlermeldung mit der Aufschrift "error. Blah blah blah". Sie kehren zur Liste der E-Mails zurück und haben immer noch die E-Mails ausgewählt, die sie löschen möchten. Sie könnten versuchen, sie erneut zu löschen.

Es gibt auch andere technische Risiken für die Ausführung von nicht blockierenden AJAX-Anforderungen. Der Benutzer könnte den Browser schließen, zu einer anderen Website navigieren und zu einem anderen Ort im aktuellen Web navigieren, wodurch der Kontext einer Fehlerreaktion bedeutungslos wird.

Warum wird es so beliebt?

Facebook, Google, Microsoft usw. usw. In all diesen großen Domänen werden zunehmend nicht blockierende AJAX-Anforderungen verwendet, damit Vorgänge so aussehen , als würden sie sofort ausgeführt. Ich habe auch eine Zunahme von Formular-Editoren festgestellt, die keine Schaltfläche zum Speichern oder Senden haben . Sobald Sie ein Feld verlassen oder die Eingabetaste drücken. Der Wert wird gespeichert. Es wurde keine Nachricht oder kein Speicherschritt für Ihr Profil aktualisiert .

AJAX-Anforderungen sind keine Gewissheit und sollten erst nach Abschluss als erfolgreich behandelt werden, aber so viele wichtige Webanwendungen funktionieren genauso.

Sind diese Websites, die nicht blockierende AJAX-Aufrufe verwenden, um reaktionsfähige Anwendungen zu simulieren, die ein unnötiges Risiko eingehen, auf Kosten des schnellen Erscheinens?

Ist dies ein Entwurfsmuster, dem wir alle folgen sollten, um wettbewerbsfähig zu bleiben?

Reactgular
quelle
20
Dies ist durch die Tatsache gerechtfertigt, dass ein erfolgreicher Betrieb viel wahrscheinlicher ist. Daher ist es ein schlechter Kompromiss, wenn Sie nur langsam vorgehen, um den seltenen Fall eines zu optimistischen Feedbacks zu vermeiden. Würden Sie lieber mit einer ruhigen, sonnigen Person interagieren oder mit jemandem, der kategorisch davon ausgeht, dass alles, was schief gehen kann, schief geht und entsprechend handelt?
Kilian Foth
1
Für mich ist es ein Problem, dass bei einer Desktop-Anwendung sowohl der Vorgang als auch der Fehler sofort auftreten. Wobei bei Webanwendungen der Vorgang sofort erfolgt, der Fehler jedoch verzögert ist. Websites arbeiten jedoch mit dem Design einer Desktopanwendung.
Reactgular
7
Haben Sie auch darüber nachgedacht, was passiert, wenn Ihre Desktop-Anwendung auf die Festplatte schreibt, tatsächlich in einen Betriebssystempuffer wechselt und die Festplatte ausfällt, bevor sie auf den Plattenteller geschrieben werden kann? Oder die Festplatte schlägt fehl, nachdem die Bytes auf den Plattenteller geschrieben wurden. In beiden Fällen denkt der Benutzer, dass etwas passiert ist, wenn es wirklich nicht passiert ist.
kdgregory
2
@KilianFoth Ich würde denjenigen vorziehen, der annimmt, dass alles schief gehen kann, wenn die "sonnige" Person Sie schlagen und Ihre Brieftasche bei den ersten Anzeichen von Schwierigkeiten stehlen wird. Es kommt also darauf an, wie stark die Seite auf einen Fehler reagiert.
Izkata
1
@ ShuttleButkus Ich denke, diese speichernden Nachrichten sind neu. Sie waren nicht da, als ich die Frage stellte. Ich habe festgestellt, dass Google in letzter Zeit mehr Feedback hinzufügt, das im Hintergrund erledigt wird.
Reactgular

Antworten:

62

Es geht nicht so sehr um "falsche" Leistung, sondern um echte Reaktionsfähigkeit. Es gibt eine Reihe von Gründen, warum es beliebt ist:

  • Internetverbindungen sind heutzutage ziemlich zuverlässig. Das Risiko, dass eine AJAX-Anfrage fehlschlägt, ist sehr gering.
  • Die ausgeführten Operationen sind nicht wirklich sicherheitskritisch. Wenn Ihre E-Mails nicht auf dem Server gelöscht werden, müssen Sie sie im schlimmsten Fall erneut löschen, wenn Sie das nächste Mal auf die Seite gelangen.
  • Sie können Ihre Seite so gestalten, dass die Aktion rückgängig gemacht wird, wenn die Anforderung fehlschlägt, aber Sie müssen nicht so subtil sein, da dies bedeutet, dass Ihre Verbindung zum Server unterbrochen ist. Es ist einfacher zu sagen, dass die Verbindung unterbrochen wurde. Letzte Änderungen können nicht gespeichert werden. Versuchen Sie es später erneut.
  • Sie können Ihre Seite so gestalten, dass nur eine ausstehende AJAX-Anfrage zugelassen wird, damit Ihr Status nicht zu stark vom Server synchronisiert wird.
  • Der Browser warnt Sie, wenn Sie versuchen, eine Seite zu schließen oder zu verlassen, während eine AJAX-Anfrage ansteht.

AJAX-Warnung ausstehend

Karl Bielefeldt
quelle
8
Tun das alle Browser standardmäßig?
Svish
Ich weiß es nicht. Ich habe es nur mit IE9 und dem neuesten Chrome getestet.
Karl Bielefeldt
3
Sie sind offensichtlich nicht mit dem australischen Internet vertraut, ganz zu schweigen von armen, sich entwickelnden und isolierten Orten, die sogar auf einem fahrenden Fahrzeug mobil sind ...
Hippietrail
2
@ Hippietrail Nun, Sie können nicht immer alle glücklich machen.
KOVIKO
1
Wenn der Benutzer eine Anfrage sendet, fordert er nicht immer eine neue Seite an. Ich denke, dass gut gestaltete AJAX-Anwendungen sie unterhaltsamer machen und den Benutzer effizienter über die aktuellen Vorgänge informieren können als bei einem Reload.
Frederik.L
32

Angenommen, es funktioniert etwas und es wird ein Fehler angezeigt, falls dies auf der Remote-Seite fehlschlägt. Dies ist weitaus benutzerfreundlicher, als den Benutzer daran zu hindern, etwas anderes zu tun, bis eine Antwort vom Server eingeht.

Ein E-Mail-Client ist tatsächlich ein gutes Beispiel dafür: Wenn ich eine Liste mit 5 E-Mails habe und die oberste ausgewählt habe, gehe ich davon aus, dass beim DELdreifachen Treffer die ersten drei E-Mails gelöscht werden. Bei "nicht blockierendem AJAX" funktioniert dies einwandfrei - jedes Mal, wenn ich die Taste drücke, wird die ausgewählte E-Mail sofort entfernt. Wenn etwas schief geht, wird ein Fehler angezeigt, und entweder werden die nicht ordnungsgemäß gelöschten E-Mails erneut angezeigt, ODER die Seite wird neu geladen, um den inkonsistenten lokalen Status zu beseitigen.

Im häufigsten Fall - das ist Erfolg - verbessert es die Benutzerfreundlichkeit. In dem seltenen Fall - Fehler - wird die Benutzerfreundlichkeit beeinträchtigt (gelöschtes Element wird erneut angezeigt oder die Anwendung wird "neu gestartet"). Wenn Sie jedoch eine Anwendung erstellen, möchten Sie in der Regel die bestmögliche Benutzerfreundlichkeit für häufige Fälle erzielen, nicht für den Fall von Fehlern.

Diebesmeister
quelle
1
+1 Das ist genau das Richtige. Heutzutage wird so viel Sicherheit standardmäßig implementiert, dass Sie im schlimmsten Fall immer noch keine echten Benutzerfehler riskieren: Stellen Sie sich vor, der E-Mail-Client kann nicht gelöscht werden, der lokale Status ist jetzt schlecht, und Sie versuchen, die falsch ausgerichtete E-Mail 4 zu löschen Mit dem Server verfügt die überwiegende Mehrheit der Back-End-Entwickler über eine Sicherheitsfunktion, die sicherstellt, dass Sie nur das löschen, was der Benutzer unbedingt möchte. Diese Fehlausrichtung führt nicht zu fehlerhaften Löschvorgängen (sie schlägt möglicherweise fehl, wird jedoch nicht gelöscht). .
Jimmy Hoffa
@ JimmyHoffa würden Sie eine eindeutige E-Mail-ID in der Löschanforderung verwenden. Es wäre wirklich schlecht, Löschanforderungen basierend auf der willkürlichen Anzeigereihenfolge der E-Mails in Ihrem Posteingang zu senden.
Buttle Butkus
14

Die Benutzer kümmern sich nicht darum, was Ihre Software hinter den Kulissen tut: Sie möchten, dass ihre Aktionen sichtbare Auswirkungen haben und in der Lage sind, in ihrem Tempo zu arbeiten.

Wenn eine Aktion auf Client-Seite erfolgreich war - wie das Löschen von E-Mails - ist es Ihre Aufgabe, sie auch auf Server-Seite erfolgreich zu machen. Warum ist die Löschung fehlgeschlagen? Wenn es sich um eine Einschränkung handelt (zum Beispiel können Sie eine archivierte E-Mail nicht entfernen), sollte der Benutzer darauf hingewiesen werden, bevor seine Aktion fehlschlägt.

Wenn der Fehler durch etwas Schwerwiegenderes verursacht wird (z. B. einen Datenbankabsturz), sollten Sie eine Möglichkeit haben, den Vorgang zu speichern und erneut zu versuchen, wenn das System wieder in Betrieb ist.

Ein gutes Beispiel dafür ist die Art und Weise, wie Facebook mit dem Chat umgeht. Es gibt keine Möglichkeit, einen Benutzer daran zu hindern, die Verbindung plötzlich zu trennen. Dies bedeutet, dass er die von Ihnen gesendeten Nachrichten nicht lesen kann, bevor er sie hinterlassen hat. Anstatt einen Fehler anzuzeigen, speichert das System alle diese Nachrichten und stellt sie dem Benutzer zur Verfügung, wenn er zurückkommt. Es gehen keine Daten verloren.

DistantEcho
quelle
2
+1. Exzellentes Beispiel für einen Chat. Die meisten Benutzer erwarten, dass ihre Nachricht sofort allen zur Verfügung gestellt wird, und da solche Nachrichten selten fehlschlagen, wird den Benutzern die Illusion vermittelt, dass dies der Fall ist.
Neil
1
@ Niphra, "Warum ist das Löschen fehlgeschlagen?" Das Netzwerk kann aus vielen Gründen ausfallen, von denen keiner mit Ihrer Anwendung zu tun hat. Es gibt nichts was Sie tun können , dass zu stoppen.
Pacerier
5

Sie können zwischen den beiden Optionen einen Kompromiss eingehen. Wenn der Benutzer beispielsweise eine E-Mail löscht, können Sie sie rot oder grau markieren, bis Sie eine Bestätigung vom Server erhalten, und sie erst dann aus der Liste entfernen. Während eine Aktion ansteht, kann der Benutzer noch andere Aktionen ausführen, sodass sie nicht blockiert werden. Der Benutzer wird jedoch daran erinnert, dass seine Aktionen noch nicht festgeschrieben wurden.

Amazon AWS geht folgendermaßen vor: Wenn Sie eine Instanz anhalten / starten, wird das Kontrollkästchen, mit dem Sie sie auswählen können, zu einem Drehfeld (Sie können also einige Sekunden lang nichts dagegen tun), dies blockiert Sie jedoch nicht Interaktion mit anderen Instanzen.

Valtron
quelle
Ihr Vorschlag ähnelt dem in Google Mail angezeigten Text "Speichern ...", während die XHR ausgeführt wird, und "Gespeichert", nachdem der Vorgang abgeschlossen wurde. Wenn immer "Gespeichert" stand, wer würde es glauben?
Buttle Butkus
3

Ich denke, dies trifft auf immer mehr Websites zu, die sich wie Anwendungen verhalten und mehr im Browser verarbeiten (z. B. Formulardaten validieren) als herkömmliche Websites. Ich sehe darin kein allzu großes Problem, solange Ihr Code zuverlässig ist und Sie davon ausgehen können, dass er unter normalen Bedingungen erfolgreich ist.

Sie sagen: "Es ist zu diesem Zeitpunkt, als der JavaScript-Code feststellt, dass die AJAX-Anforderung fehlgeschlagen ist. Das Skript könnte eine Fehlermeldung anzeigen, aber es ist zu diesem Zeitpunkt wirklich sinnlos."

Warum sollte es sinnlos sein? Sie können in die Liste der E-Mails zurückkehren und den Löschvorgang erneut ausführen. Warum stattdessen warten? Es gibt eigentlich kein großes "Risiko" und sie "scheinen" nicht schnell zu sein, sie arbeiten tatsächlich schneller. Also, wenn die Aktivität nicht "kritisch" ist, warum langsam sein?

thorsten müller
quelle
1
Vielleicht war sinnlos nicht das richtige Wort, aber ich meine, dass der Fehlermeldung ein relativer Kontext fehlt, weil der Benutzer jetzt etwas völlig anderes tut. Ich versuche zu sagen, dass ein ignoranter Webbenutzer dachte, dass die E-Mails erfolgreich gelöscht wurden. Warum erhalten sie nun später eine Fehlermeldung für etwas, das sie "gesehen" haben, das entfernt wurde? Für uns Programmierer verstehen wir, aber für Großväter, die Google Mail verwenden, würden sie das nicht verstehen.
Reactgular
Die meisten Benutzer möchten lieber eine Anwendung verwenden, bei der Dinge sofort geschehen, das System reagiert und die Benutzeroberfläche bei einem Fehler mit einer Wahrscheinlichkeit von 1 zu 10.000 auf ungewöhnliche Weise aktualisiert wird, als eine Anwendung, die bei jeder Änderung eines Werts für eine Sekunde abstürzt.
Gort the Robot
1

Mein 2c ist: Es gibt Situationen, in denen es besser ist, Ajax-Operationen "nicht zu blockieren" und andere, bei denen es sich um eine schlechte Design-Wahl handelt. Beispiel: Abstimmung eines YouTube-Videos. Sie möchten nicht wirklich, dass ein Teil der Seite blockiert wird, während Sie auf die kleinen Starts dort klicken. Es ist besser, leise zu scheitern. Sogar eine Bestätigungsnachricht wäre übertrieben. Ihr Beispiel mit E-Mail-Löschung ist jedoch obligatorisch für Ajax-Anforderungen vom Blockierungstyp.

Mongo DB macht so etwas (und dies könnte als Beispiel für eine Desktop-Anwendung angesehen werden). Sie haben verschiedene "Schreibprobleme" für ihre Vorgänge, und Sie können sie für jeden Vorgang auf unterschiedliche Werte konfigurieren, von "Sofort zurückkehren und auf nichts warten" bis "Blockieren", bis Sie die Bestätigung der erfolgreichen Netzwerkübertragung haben und kehren Sie dann zu "Warten Sie, bis der Inhalt ordnungsgemäß für das Schreiben auf dem Remotecomputer geplant ist, bevor Sie zurückkehren" zurück. Wenn Sie Desktop-Thick-Clients (wie C ++) mit dem Mongo-Treiber erstellen, würden Sie natürlich die geringsten Schreibprobleme für DB-Vorgänge mit minimaler "Kritikalität" (z. B. das Überprüfen auf neue E-Mails) und andere Probleme mit strengeren Schreibproblemen festlegen .

Obwohl ich die Nützlichkeit von nicht blockierendem Ajax sehe, stimme ich Ihnen zu, dass es zu viel passiert. Zu einem Zeitpunkt gab es mindestens eine berühmte "Social Networking" -Seite, die dies für das Hochladen von Fotos tun würde. Sie würden Ihr Foto zum Hochladen auswählen und dann loslegen. Sofort würde es Ihnen sagen, dass es fertig ist, und dann sicher genug, wenn Sie am nächsten Tag weitere Fotos hinzufügen möchten (oder das verwenden, von dem Sie dachten, dass Sie es bereits hinzugefügt haben) war nie zu finden. Später gaben sie dies auf und nahmen sich tatsächlich die Zeit, auf eine Antwort zu warten (und Sie bekamen in der Tat manchmal Nachrichten wie "Foto konnte nicht hochgeladen werden, später versuchen").

Shivan Drache
quelle
+1 dafür, dass ich die Dinge so sehe :). Der Foto-Upload ist ein gutes Beispiel dafür, dass dies fehlschlägt.
Reactgular
1
Warum ist ein blockierender Upload vorzuziehen? In Picasa (Web - Interface) können Sie Fotos in, ziehen , während sie im Hintergrund hochladen, können Sie mehr in oder Tag - Fotos ziehen, fertig sind, usw. Für einen Sperr Upload - Vorgang würde , dass ein schrecklicher UX
BLSully