Jak bezpieczne są ukryte żądania AJAX, które udają działanie?

48

Co to jest ukryte żądanie AJAX?

Zauważyłem wzrost użycia ukrytych żądań AJAX zaprojektowanych tak, aby akcja użytkownika wydawała się natychmiastowa. Ten typ żądania AJAX będę określać jako nieblokujący. Jest to żądanie AJAX złożone bez uświadomienia użytkownikowi, że się dzieje, jest wykonywane w tle, a jego działanie jest ciche ( nie ma żadnych szczegółowych informacji o pomyślnym zakończeniu połączenia AJAX ). Celem jest sprawienie, aby operacja wyglądała na natychmiastową, gdy naprawdę się nie zakończyła.

Oto przykłady nieblokującego żądania AJAX;

  • Użytkownik klika usuń zbiór e-maili. Przedmioty znikają natychmiast ze skrzynki odbiorczej i mogą kontynuować inne operacje. Tymczasem żądanie AJAX przetwarza usunięcie elementów w tle.
  • Użytkownik wypełnia formularz dotyczący nowych rekordów. Kliknięcia zapisz. Nowy element pojawi się na liście natychmiast. Użytkownik może nadal dodawać nowe rekordy.

Aby to wyjaśnić, oto przykłady blokowania żądania AJAX;

  • Użytkownik klika usuń zbiór e-maili. Pojawi się kursor klepsydry. Żądanie AJAX jest wysyłane, a gdy odpowiada, kursor klepsydry jest wyłączany. Użytkownik musi poczekać sekundę na zakończenie operacji.
  • Użytkownik wypełnia formularz dotyczący nowych rekordów. Kliknięcia zapisz. Formularz zmienia kolor na szary z animacją modułu ładującego AJAX. Wyświetlany jest komunikat „Twoje dane zostały zapisane”, a nowy rekord pojawia się na liście.

Różnica między dwoma powyższymi scenariuszami polega na tym, że nieblokująca konfiguracja AJAX nie zapewnia informacji zwrotnej o wydajności operacyjnej, a blokująca konfiguracja AJAX tak.

Ryzyko ukrytych żądań AJAX

Największe ryzyko tego typu żądania AJAX polega na tym, że aplikacja internetowa może być w zupełnie innym stanie, gdy żądanie AJAX zawiedzie.

Na przykład przykład nieblokujący;

  • Użytkownik wybiera kilka wiadomości e-mail. Klika przycisk usuwania. Wydaje się, że operacja odbywa się natychmiast (elementy po prostu znikają z listy). Następnie użytkownik klika przycisk tworzenia i zaczyna pisać nowy e-mail. W tej chwili kod JavaScript wykrywa, że ​​żądanie AJAX nie powiodło się. Skrypt może wyświetlać komunikat o błędzie, ale w tej chwili jest to naprawdę bezcelowe.

Alternatywnie przykład blokujący;

  • Użytkownik wybiera kilka wiadomości e-mail. Klika przycisk usuwania. Widzi klepsydrę, ale operacja kończy się niepowodzeniem. Otrzymują komunikat o błędzie „błąd. Bla bla bla”. Wracają z powrotem do listy wiadomości e-mail i nadal mają wybrane wiadomości e-mail, które chcieli usunąć. Mogą spróbować je usunąć ponownie.

Istnieją również inne zagrożenia techniczne związane z wykonywaniem nieblokujących żądań AJAX. Użytkownik może zamknąć przeglądarkę, przejść do innej witryny i może przejść do innej lokalizacji w bieżącej sieci, co sprawia, że ​​kontekst jakiejkolwiek reakcji na błąd jest bez znaczenia.

Dlaczego więc staje się tak popularny?

Facebook, Google, Microsoft itp. Itd. Itd. Wszystkie te duże domeny coraz częściej korzystają z nieblokujących żądań AJAX, aby wydawać się , że operacje są wykonywane natychmiast. Zauważyłem również wzrost liczby edytorów formularzy, które nie mają przycisku Zapisz ani Prześlij . Jak tylko opuścisz pole lub naciśniesz enter. Wartość zostaje zapisana. Nie ma Twój profil został zaktualizowany krok wiadomość lub zapisywania.

Żądania AJAX nie są pewne i nie powinny być traktowane jako zakończone sukcesem, dopóki się nie zakończą, ale tak wiele dużych aplikacji internetowych działa właśnie tak.

Czy te witryny wykorzystują nieblokujące wywołania AJAX do symulacji responsywnych aplikacji, podejmując niepotrzebne ryzyko kosztem szybkiego pojawiania się?

Czy to wzór, który powinniśmy wszyscy stosować, aby pozostać konkurencyjnym?

Reactgular
źródło
20
Jest to uzasadnione faktem, że udane działanie jest znacznie bardziej prawdopodobne, dlatego powolność, aby uniknąć rzadkiego przypadku nadmiernie optymistycznych informacji zwrotnych, jest złym kompromisem. Czy po przeniesieniu do osobistych relacji wolisz raczej wchodzić w interakcję ze spokojną, słoneczną osobą lub osobą, która kategorycznie zakłada, że ​​wszystko, co może pójść nie tak, pójdzie nie tak i działa odpowiednio?
Kilian Foth
1
Dla mnie walczę o to, że aplikacja komputerowa ma natychmiastowe działanie i błąd. Gdzie, jak w przypadku aplikacji internetowych, operacja odbywa się natychmiast, ale błąd jest opóźniony. Jednak witryny działają przy projektowaniu aplikacji komputerowej.
Reactgular
7
Czy zastanawiałeś się również, co się dzieje, gdy aplikacja komputerowa zapisuje na dysk, faktycznie przechodzi do bufora systemu operacyjnego, a dysk ulega awarii, zanim można go zapisać na talerzu? Lub, jeśli o to chodzi, dysk ulega awarii po zapisaniu bajtów na talerzu. W obu przypadkach użytkownik uważa, że coś się wydarzyło, a tak naprawdę nie miało miejsca.
kdgregory
2
@KilianFoth Wolę, aby ten, który zakłada, że ​​wszystko pójdzie nie tak, jeśli „słoneczna” osoba uderzy cię i ukradnie portfel przy pierwszych oznakach kłopotów. To zależy od skali reakcji strony na awarię.
Izkata
1
@ButtleButkus Myślę, że te zapisujące wiadomości są nowe. Nie było ich, kiedy zadałem pytanie. Zauważyłem, że Google ostatnio dodaje więcej opinii, że robi to w tle.
Reactgular,

Odpowiedzi:

62

To nie tyle „fałszywe” działanie, co prawdziwa reakcja. Istnieje wiele powodów, dla których jest popularny:

  • Połączenia internetowe są obecnie dość niezawodne. Ryzyko niepowodzenia żądania AJAX jest bardzo niskie.
  • Wykonywane operacje nie są tak naprawdę kluczowe dla bezpieczeństwa. Jeśli twoje e-maile nie zostaną usunięte na serwerze, najgorsze, co się stanie, to musisz je usunąć ponownie przy następnym wejściu na stronę.
  • Możesz zaprojektować swoją stronę tak, aby cofała akcję, jeśli żądanie się nie powiedzie, ale tak naprawdę nie musisz być tak subtelny, ponieważ oznacza to, że połączenie z serwerem zostało zerwane. Łatwiej powiedzieć „Utracono połączenie. Nie można zapisać ostatnich zmian. Spróbuj ponownie później”.
  • Możesz zaprojektować stronę tak, aby zezwalała tylko na jedno oczekujące żądanie AJAX, dzięki czemu Twój stan nie będzie zbyt zsynchronizowany z serwerem.
  • Przeglądarka ostrzega cię, jeśli spróbujesz zamknąć stronę lub opuścić stronę w oczekiwaniu na żądanie AJAX.

AJAX oczekuje na ostrzeżenie

Karl Bielefeldt
źródło
8
W ostatnim punkcie, czy wszystkie przeglądarki domyślnie to robią?
Svish
Nie wiem Testowałem to tylko na IE9 i najnowszym chrome.
Karl Bielefeldt
3
Oczywiście nie znasz australijskiego Internetu, nie wspominając o biednych, rozwijających się i odizolowanych miejscach, nawet mobilnych w jadącym pojeździe ...
hippietrail
2
@hippietrail Cóż, nie możesz uszczęśliwić wszystkich przez cały czas.
KOVIKO,
1
Gdy użytkownik wysyła żądanie, nie zawsze prosi o nową stronę. Myślę, że dobrze zaprojektowane aplikacje AJAX mogą sprawić, że będą one bardziej przyjemne, informując użytkownika o tym, co dzieje się bardziej efektywnie niż po ponownym załadowaniu.
Frederik.L,
32

Zakładanie, że coś zadziała i wyświetlanie błędu w przypadku niepowodzenia po stronie zdalnej, jest o wiele bardziej przyjazne dla użytkownika niż blokowanie użytkownikowi wykonywania innych czynności, dopóki nie pojawi się odpowiedź z serwera.

Klient poczty e-mail jest w rzeczywistości doskonałym przykładem tego: gdy mam listę z 5 wiadomościami e-mail i wybrano DELpierwszą, oczekuję, że po trzykrotnym naciśnięciu pierwsze trzy wiadomości e-mail zostaną usunięte. W przypadku „nieblokującego AJAX” działa to dobrze - za każdym razem, gdy naciskam klawisz, wybrany e-mail jest natychmiast usuwany. Jeśli coś pójdzie nie tak, wyświetlany jest błąd i albo ponownie niepoprawnie usunięte e-maile są LUB LUB strona jest ładowana ponownie, aby pozbyć się niespójnego stanu lokalnego.

Zatem w najczęstszym przypadku - czyli sukcesie - poprawia użyteczność. W rzadkim przypadku - awarii - użyteczność jest obniżana (usunięty element pojawia się ponownie lub aplikacja jest „restartowana”), ale podczas tworzenia aplikacji zwykle chcesz mieć najlepszą użyteczność w typowych przypadkach, a nie w przypadku błędów.

ThiefMaster
źródło
1
+1 to miejsce w sercu sprawy. Obecnie domyślnie jest tak dużo bezpieczeństwa, że ​​ludzie wdrażają, że w najgorszym przypadku nadal nie ryzykujesz prawdziwych błędów użytkownika: wyobraź sobie, że klient poczty e-mail nie usuwa, teraz stan lokalny jest zły i próbują usunąć wiadomość e-mail 4, która jest źle wyrównana z serwerem zdecydowana większość deweloperów zaplecza będzie tam miała blokadę bezpieczeństwa, aby zapewnić, że usuniesz tylko to, czego użytkownik absolutnie chce, a więc to przesunięcie nie spowoduje błędnych usunięć (może się nie powieść, ale nie zostanie usunięte) .
Jimmy Hoffa
@ JimmyHoffa użyjesz unikalnego identyfikatora e-mail w żądaniu usunięcia. Naprawdę źle byłoby wysyłać żądania usunięcia na podstawie dowolnej kolejności wyświetlania wiadomości e-mail w skrzynce odbiorczej.
Buttle Butkus
14

Użytkownicy nie dbają o to, co robi Twoje oprogramowanie za kulisami: chcą, aby ich działania miały widoczny wpływ i były w stanie pracować w swoim tempie.

Jeśli akcja zakończyła się powodzeniem po stronie klienta - na przykład usunięcie wiadomości e-mail - Twoim zadaniem jest, aby zakończyła się powodzeniem również po stronie serwera. Dlaczego usunięcie nie powiodło się? Jeśli wynika to z jakiegoś ograniczenia (na przykład nie możesz usunąć zarchiwizowanego e-maila), użytkownik powinien zostać o tym poinformowany, zanim jego działanie się nie powiedzie.

Jeśli błąd jest spowodowany przez coś poważniejszego (powiedzmy, awaria bazy danych), powinieneś mieć sposób na zapisanie operacji i ponowną próbę, gdy system będzie ponownie uruchomiony.

Dobrym przykładem zarządzania tym jest sposób, w jaki Facebook obsługuje czat. Nie ma sposobu, aby powstrzymać użytkownika przed rozłączeniem się nagle, co oznacza, że ​​nie będzie w stanie odczytać wiadomości wysłanych przed jego odejściem. Zamiast wyświetlać błąd, system zapisuje wszystkie te wiadomości i udostępnia je użytkownikowi, gdy wróci. Żadne dane nie zostaną utracone.

DistantEcho
źródło
2
+1. Doskonały przykładowy czat. Większość użytkowników oczekuje, że ich wiadomość zostanie natychmiast udostępniona wszystkim, a ponieważ takie wiadomości rzadko zawodzą, użytkownicy mają złudzenie, że tak jest.
Neil
1
@Niphra: „Dlaczego usunięcie nie powiodło się?” Sieć może zawieść z wielu powodów, z których żaden nie ma związku z twoją aplikacją. Tam nic nie można zrobić, aby powstrzymać to.
Pacerier
5

Możesz iść na kompromis między dwiema opcjami. Na przykład, jeśli użytkownik usunie wiadomość e-mail, możesz oznaczyć ją na czerwono lub wyszarzyć, dopóki nie otrzymasz potwierdzenia z serwera, a dopiero potem usuń ją z listy. Użytkownik może nadal robić inne rzeczy, gdy jedna akcja jest w toku, więc nie blokuje, ale nadal pozostawia małe przypomnienie dla użytkownika, że ​​jego akcje nie zostały jeszcze zatwierdzone.

Amazon AWS przyjmuje takie podejście: po zatrzymaniu / uruchomieniu instancji pole wyboru, które pozwala ci wybrać, zmienia się w spinner (więc nie możesz nic z tym zrobić przez kilka sekund), ale to nie blokuje interakcja z innymi instancjami.

valtron
źródło
Twoja sugestia jest podobna do tego, jak Gmail wyświetla tekst „Zapisywanie ...” podczas XHR i „Zapisano” po zakończeniu. Gdyby zawsze mówił „ocalony”, kto by w to uwierzył?
Buttle Butkus
3

Myślę, że towarzyszy temu coraz więcej stron internetowych, które próbują zachowywać się jak aplikacje i przetwarzają w przeglądarce więcej (jak np. Sprawdzanie poprawności danych formularza) niż tradycyjne witryny. Nie widzę w tym zbyt dużego problemu, o ile Twój kod jest niezawodny i możesz oczekiwać, że odniesie sukces w normalnych warunkach.

Mówisz: „W tej chwili kod JavaScript wykrywa, że ​​żądanie AJAX nie powiodło się. Skrypt może wyświetlać komunikat o błędzie, ale w tej chwili jest to naprawdę bezcelowe”.

Dlaczego miałoby to być bezcelowe? Możesz wrócić na listę wiadomości e-mail i ponownie usunąć. Po co zamiast tego czekać? W rzeczywistości nie ma zbyt dużego „ryzyka” i nie „wydają się” być szybkie, w rzeczywistości działają szybciej. Więc jeśli aktywność nie jest „krytyczna”, po co być powolnym?

Thorsten Müller
źródło
1
Być może bezcelowe nie było właściwe słowo, ale mam na myśli to, że komunikat o błędzie nie ma względnego kontekstu, ponieważ użytkownik robi teraz coś zupełnie innego. Staram się powiedzieć, że dla nieświadomego użytkownika sieci myśleli, że e-maile zostały pomyślnie usunięte. Dlaczego więc teraz otrzymają komunikat o błędzie dotyczący czegoś, co „widzieli” zostały usunięte. Dla nas, programistów, rozumiemy, ale dla dziadka używającego Gmaila nie zrozumieliby.
Reactgular
Większość ludzi wolałaby korzystać z aplikacji, w których wszystko dzieje się natychmiast, system reaguje i istnieje 1 na 10 000 szans, że interfejs użytkownika może dziwnie zaktualizować błąd, niż aplikacja, która zawiesza się na sekundę przy każdej zmianie wartości.
Gort the Robot
1

Moje 2c brzmi: są sytuacje, w których lepiej, jak to ująłeś, mieć „nieblokujące” operacje Ajax i inne, gdzie jest to zły wybór projektu. Przykład: głosowanie na wideo w YouTube. Naprawdę nie chcesz, aby jakakolwiek część strony była blokowana, gdy klikniesz małe początkowe strony. Lepiej po cichu zawieść. Nawet wiadomość potwierdzająca byłaby nadmiernym zabójstwem. Jednak twój przykład z usunięciem wiadomości e-mail kwalifikowałbym się jako obowiązkowy dla żądania blokowania Ajax.

Mongo DB robi coś takiego (i można to uznać za przykład aplikacji komputerowej). Mają różne „obawy zapisu” dla swoich operacji, i możesz skonfigurować różne wartości dla każdej operacji, od „powróć natychmiast i nie czekaj na nic” na „zablokuj”, dopóki nie potwierdzisz pomyślnego transferu sieci i następnie zwróć „do”, zanim zawartość zostanie poprawnie zaplanowana na zapis dysku na zdalnym komputerze. Oczywiście, jeśli tworzysz grubego klienta Desktop (podobnie jak C ++) przy użyciu sterownika Mongo, ustawiałbyś najlżejsze obawy dotyczące zapisu dla operacji db o minimalnej „krytyczności” (takich jak sprawdzanie nowej wiadomości e-mail), a inne na bardziej rygorystycznych obawach dotyczących zapisu .

Chociaż widzę przydatność nieblokującego Ajaxa, zgadzam się z tobą, że dzieje się to zbyt wiele. W pewnym momencie istniała przynajmniej jedna znana witryna „sieci społecznościowych”, która robiłaby to w celu przesyłania zdjęć. Wybrałeś swoje zdjęcie do przesłania, a potem bam, od razu powiedziałoby ci, że jest zrobione, a potem na pewno następnego dnia, gdy chcesz dodać więcej zdjęć (lub użyć tego, o którym myślałeś, że już dodałeś), to nigdy nie można było znaleźć. Później zrezygnowali z tego i faktycznie poświęcili czas na odpowiedź (i rzeczywiście czasami dostawali wiadomości typu „nie udało się przesłać zdjęcia, spróbuj później”).

Shivan Dragon
źródło
+1 za oglądanie rzeczy po swojemu :). Przesyłanie zdjęć jest doskonałym przykładem tego, że się nie udaje.
Reactgular
1
Dlaczego przesyłanie blokujące byłoby lepsze? W programie Picasa (interfejs internetowy) możesz przeciągać zdjęcia, a podczas przesyłania w tle możesz przeciągać więcej lub oznaczać zdjęcia, które zostały zakończone itp. Operacja blokowania przesyłania sprawiłaby, że to straszne UX
BLSully