Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ XML, AJAX _ Ajax - async: false

Napisany przez: topcio 19.03.2018, 22:00:30

Witajcie
mam funkcję weryfikującą hasło, która działa tylko kiedy wyłączona jest asynchroniczność, w konsoli pisze, że asynchroniczność zostanie niedługo wyłączona
czy istnieje jakiś inny sposób na synchroniczne zapytanie typu ajax?

[JAVASCRIPT] pobierz, plaintext
  1. passVerification = function () {
  2. var testowe = $.ajax({
  3. type: "POST",
  4. async: false,
  5. cache: false,
  6. url: "../php_function/user/user.php",
  7. data: $('#unblock_UI_confirm').parents("form").serializeArray()
  8. });
  9. var session_unfrozen = $.ajax({
  10. type: "POST",
  11. async: false,
  12. cache: false,
  13. url: "../php_function/user/user.php",
  14. data: { ajax_test:"user_session_unfrozen" }
  15. });
  16.  
  17. testowe.done(function (value) {
  18. if (value == 'veryfication success') {
  19. console.log('hasło OK');
  20. session_unfrozen.done(function (val) {
  21. if (val == 'session_unfrozen') {
  22. console.log('odblokowany');
  23. destroyWarningDialog();
  24. stopDialogTimer();
  25. startIdleTimer();
  26.  
  27. }
  28. else {
  29. event.preventDefault();
  30. event.stopPropagation();
  31. console.log('sesja nie odblokowana');
  32. }
  33. })
  34. }
  35. else {
  36. event.preventDefault();
  37. event.stopPropagation();
  38. console.log('zle haslo');
  39. //logoutUser();
  40. }
  41. });
  42. };
[JAVASCRIPT] pobierz, plaintext

Napisany przez: trueblue 19.03.2018, 22:08:38

Oczywiście, że jest. Zmienić async na true...

Dlaczego po prostu tego drugiego wywołania ajax nie wstawisz do callback pierwszego wywołania?

Napisany przez: topcio 19.03.2018, 22:15:40

Cytat(trueblue @ 19.03.2018, 22:08:38 ) *
Oczywiście, że jest. Zmienić async na true...

Dlaczego po prostu tego drugiego wywołania ajax nie wstawisz do callback pierwszego wywołania?


No właśnie jak mam na true to nie działa, bo chyba nie czeka na informację zwrotną i leci dalej, dopiero jak zmieniłem na false to zaczęło działać poprawnie.

Cytat
Dlaczego po prostu tego drugiego wywołania ajax nie wstawisz do callback pierwszego wywołania?

Bo nie bardzo wiem jak.

Napisany przez: trueblue 19.03.2018, 22:20:25

Na analogicznej zasadzie jak wstawiłeś linię 19.

Napisany przez: topcio 19.03.2018, 22:50:06

coś w ten deseń

[JAVASCRIPT] pobierz, plaintext
  1. $.when(testowe, session_unfrozen).done(function(a1, a2){
  2. if ((a1[0] == 'veryfication success') && ( a2[0] == 'session_unfrozen')) {
  3. console.log(a1 + ' ' + a2);
  4. destroyWarningDialog();
  5. stopDialogTimer();
  6. startIdleTimer();
  7. }
  8. else {
  9. event.preventDefault();
  10. event.stopPropagation();
  11. }
  12.  
  13. });
[JAVASCRIPT] pobierz, plaintext

Napisany przez: SmokAnalog 19.03.2018, 22:57:16

Pytanie na początek powinno brzmieć dlaczego w ogóle chcesz rezygnować z asynchroniczności? Powinieneś tak zorganizować kod, żeby prawidłowo działał z asynchronicznym żądaniem HTTP zamiast blokować wszystkie skrypty.

Napisany przez: topcio 19.03.2018, 22:59:43

Cytat(SmokAnalog @ 19.03.2018, 22:57:16 ) *
Pytanie na początek powinno brzmieć dlaczego w ogóle chcesz rezygnować z asynchroniczności? Powinieneś tak zorganizować kod, żeby prawidłowo działał z asynchronicznym żądaniem HTTP zamiast blokować wszystkie skrypty.

Bo nie wiem jak to w inny sposób ugryźć, jak zmusić kod by najpierw poczekał na ajaxa a potem jechał dalej z koksem.

Napisany przez: SmokAnalog 19.03.2018, 23:03:56

Wygodnie się pisze kod z promise'ami, więc jeśli używasz transpilatora lub jesteś w stanie olać IE11, to polecam.

Ale z Ajaxem też można to ubrać dość ładnie. Po prostu w callbackach wywołuj kolejne działania.

Napisany przez: topcio 19.03.2018, 23:06:15

Cytat(topcio @ 19.03.2018, 22:50:06 ) *
coś w ten deseń
[JAVASCRIPT] pobierz, plaintext
  1. $.when(testowe, session_unfrozen).done(function(a1, a2){
  2. if ((a1[0] == 'veryfication success') && ( a2[0] == 'session_unfrozen')) {
  3. console.log(a1 + ' ' + a2);
  4. destroyWarningDialog();
  5. stopDialogTimer();
  6. startIdleTimer();
  7. }
  8. else {
  9. event.preventDefault();
  10. event.stopPropagation();
  11. }
  12.  
  13. });
[JAVASCRIPT] pobierz, plaintext


No to chyba tak może byćquestionmark.gif

Wiesz w ogóle z javascript bawię się od niedawna, i chyba (tak sądzę) trochę już opanowałem, ale jeszcze długa droga przede mną.
Wiem że promise to przeszłość więc pewnie się w to zagłębię.

Napisany przez: SmokAnalog 19.03.2018, 23:10:07

Nie wiem co chcesz dokładnie zrobić.

Napisany przez: topcio 19.03.2018, 23:11:46

Cytat(SmokAnalog @ 19.03.2018, 23:10:07 ) *
Nie wiem co chcesz dokładnie zrobić.

już tłumaczę.
Jest pewna funkcja
https://github.com/JillElaine/jquery-idleTimeout/blob/master/jquery-idleTimeout.js
i do tej funkcji dodaję opcję aby można było odblokować interfejs tylko po wpisaniu hasła.

Moja wersja części kodu
[JAVASCRIPT] pobierz, plaintext
  1. openWarningDialog = function () {
  2. var dialogContent = "<div id='blockUI' style='display:none;'><div id='next'><div id=\"title\"><span id=\"user_info\" class=\"huge\">" + currentConfig.userInfo + "</span><span id=\"user_info_2\" class=\"normal\">aby odblokować wprowadź swoje hasło</span></div><form id=\"unblock_UI\" enctype=\"multipart/form-data\" method=\"post\" accept-charset='UTF-8'><input type=\"hidden\" name=\"form_type\" value=\"passVerification\"><input class=\"normal\" type=\"password\" name=\"user_password\" placeholder=\"Please Enter Your Password\"><div id=\"confirm_button\"><button type=\"submit\" name=\"user_form_confirm\" id=\"unblock_UI_confirm\" value=\"passVerification\">Zatwierdź</button></div></form><div id=\"countdown\"><div id=\"countdownDisplay_preview\">automatyczne wylogowanie nastąpi za: &nbsp&nbsp</div><div id=\"countdownDisplay\"></div></div></div></div>";
  3.  
  4. $(dialogContent).fadeIn(500).appendTo("body");
  5. $('#unblock_UI_confirm').click(function(event){ passVerification(this); });
  6. countdownDisplay();
  7. document.title = currentConfig.dialogTitle;
  8. if (currentConfig.sessionKeepAliveTimer) {
  9. stopKeepSessionAlive();
  10. }
  11. };
  12.  
  13. passVerification = function () {
  14. var testowe = $.ajax({
  15. type: "POST",
  16. async: false,
  17. cache: false,
  18. url: "../php_function/user/user.php",
  19. data: $('#unblock_UI_confirm').parents("form").serializeArray()
  20. });
  21. var session_unfrozen = $.ajax({
  22. type: "POST",
  23. async: false,
  24. cache: false,
  25. url: "../php_function/user/user.php",
  26. data: { ajax_test:"user_session_unfrozen" }
  27. });
  28.  
  29. $.when(testowe, session_unfrozen).done(function(a1, a2){
  30. if ((a1[0] == 'veryfication success') && ( a2[0] == 'session_unfrozen')) {
  31. console.log(a1 + ' ' + a2);
  32. destroyWarningDialog();
  33. stopDialogTimer();
  34. startIdleTimer();
  35. }
  36. else {
  37. event.preventDefault();
  38. event.stopPropagation();
  39. }
  40. });
  41. };
[JAVASCRIPT] pobierz, plaintext

Napisany przez: SmokAnalog 19.03.2018, 23:15:53

Dlaczego nie zrobisz tego w jednym requeście?

Napisany przez: topcio 19.03.2018, 23:21:59

teoretycznie mógłbym, ale ten drugi doszedł potem, kiedy stwierdziłem, że przecież user może być zalogowany na kilku urządzeniach i w tym drugim docelowo będą dana json w mysql z konkretnymi id sesji dla usera, jeśli id sesji się zgadza to wtedy odblokuje, jeśli się nie zgadza wyloguje.

Napisany przez: SmokAnalog 19.03.2018, 23:27:13

Mimo wszystko zrobiłbym dwie rzeczy za jednym zamachem. To się chwali, że bierzesz pod uwagę możliwość bycia zalogowanym na innym urządzeniu. Nawet to forum tego nie respektuje i bezczelnie wylogowuje tongue.gif

Nadal nie do końca szczegółowo wiem co chcesz zrobić, ale wydaje mi się, że Twój kod ma kilka babolków. na przykład nie wiem po co używasz tu event.preventDefault() i event.stopPropagation().

console.log(a1 + ' ' + a2) też nie za bardzo ma sens w Twoim przypadku. Zrób sobie console.log(a1, a2);

Możesz opisać też po prostu dokładniej co chcesz zrobić - co to za apka, kiedy blokuje się interfejs jak dokładnie się go odblokowuje.

Napisany przez: topcio 19.03.2018, 23:39:06

Projekt to ogólnie rzecz biorąc system zarządzania monitoringiem wizyjnym, dla wielu lokalizacji. Do panelu mogą logować się zarówno klienci jak i obsługa systemu w zależności od uprawnień.
Jest cały czas w rozwoju, w pierwszej fazie miało to być narzędzie tylko dla mnie do zarządzania całym tym bajzlem, ale doszedłem do wniosku, że lepiej będzie jak zrobię system dla wszystkich (łącznie z podglądem on-line itp itd).
Więc jeśli ktoś sobie odpali kamerkę i np. sobie pójdzie, to po co ma mi generować non stop streeming, więc pomyślałem, że wylogowuję usera po jakiejś bezczynności. Znalazłem ten skrypcik, https://github.com/JillElaine/jquery-idleTimeout/blob/master/jquery-idleTimeout.js, fajny ale brakowało mi w nim potwierdzenia hasłem odblokowania interfejsu.
event.preventDefault() i event.stopPropagation(). tych dwóch używam, bo wydaje mi się iż główny skrypt (nie mój) reaguje na kliknięcie, ponieważ bez tego nawet jeśli hasło jest złe to i tak odblokowuje interfejs, a tego chcę uniknąć.
Pozostało mi jeszcze zaimplementowanie funkcji blokującej odświeżanie strony. Na razie mam

[JAVASCRIPT] pobierz, plaintext
  1. isDialogOpen = function () {
  2. var dialogOpen = $('#blockUI').css('display') == 'block';
  3. if (dialogOpen === true) {
  4. $(document).on('keydown', function(e) {
  5. if (e.keyCode == 9 || e.which == 9) e.preventDefault();
  6. if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault();
  7. })
  8. return true;
  9. }
  10. $(document).unbind('keydown');
  11. return false;
  12. };
[JAVASCRIPT] pobierz, plaintext

całego opisu apki to trudno dokonać tak w 5 minut tongue.gif
te dwa requesty w php wyglądają następująco:
  1. if ( $_POST['ajax_test'] == 'user_session_unfrozen' ) {
  2. if ($users->user_session_unfrozen($_SESSION['user_id']) == 'OK') {
  3. http://www.php.net/echo 'session_unfrozen';
  4. http://www.php.net/exit;
  5. }
  6. }
  7. if ( $_POST['form_type'] == 'passVerification' ) {
  8. $user = $users->get_user_data($_SESSION['user_id']);
  9. if ($user['user_pass'] == $users->code_passwd($_POST['user_password'])) {
  10. http://www.php.net/echo 'veryfication success';
  11. http://www.php.net/exit;
  12. }
  13. else {
  14. http://www.php.net/echo 'verification failed';
  15. http://www.php.net/exit;
  16. }
  17. }


Napisany przez: SmokAnalog 19.03.2018, 23:46:36

Ja raczej wyznaję taką zasadę, że nie powinno się blokować naturalnych zachowań przeglądarki, takich jak odświeżania. Aplikacja powinna sobie z nimi po prostu radzić.

Nie wiem też co to znaczy "blokowanie interfejsu" u Ciebie, ale może lepiej byłoby po prostu zrobić przekierowanie do ekranu logowania po tym czasie nieaktywności? Chyba że nadal można mieć wgląd w ekran, ale bez możliwości klikania na cokolwiek. Mógłbyś to rozwiązać na przykład tak, żeby po upływie tego czasu usunąć ciastko i przy próbie jakiegoś działania po stronie serwera wywalać odpowiedni status HTTP (np. 403 Forbidden) jak nie ma odpowiedniego ciastka. I po stronie klienta wtedy dać odpowiedni monit o wpisanie hasła. W ten sposób nie musisz trzymać żadnych tokenów ani nic takiego, jedynie informację o tym kto był zalogowany. Na przykład mieć cały czas w DOM pole do loginu i hasła, przy czym pole z loginem będzie miało ustawioną wartość na ostatniego zalogowanego, żeby ułatwić mu to ponowne logowanie.

Tak głośno myślę, bo pytanie jeszcze na ile chcesz dopieszczać to w kierunku Single Page Application.

Napisany przez: topcio 21.03.2018, 00:43:23

jak zerkniesz w konsolę po zalogowaniu to leci licznik jak dojdzie do 0 to zablokuje

Troszkę przerobiłem, jest w jednym request, teraz działa prawidłowo

[JAVASCRIPT] pobierz, plaintext
  1. passVerification = function () {
  2. console.log('Zaczynam sprawdzanie hasłe: ');
  3. console.log('Wykonuje pierwszy Ajax Request: ');
  4. var verification = $.ajax({
  5. type: "POST",
  6. async: false,
  7. cache: false,
  8. url: "../php_function/user/user.php",
  9. data: $('#unblock_UI_confirm').parents("form").serializeArray()
  10. });
  11. verification.done(function(response_01) {
  12. console.log(' Ajax Request 1: ' + $.parseJSON(response_01)[0]);
  13. });
  14. $.when(verification).done(function(verification) {
  15. var json = $.parseJSON(verification);
  16. if ((json[0] == 'veryfication_success') && ( json[1] == 'session_unfrozen')) {
  17. console.log('Ponieważ hasło i sesja OK -> odblokowuje interfejs');
  18. destroyWarningDialog();
  19. stopDialogTimer();
  20. startIdleTimer();
  21. }
  22. else if ((json[0] == 'veryfication_success') && ( json[1] == 'session_unfrozen_error')) {
  23. console.log('Hasła zgodne, brak ID sesji -> wylogowuje');
  24. logoutUser();
  25. }
  26. else if (json[0] == 'verification_failed') {
  27. console.log('Hasła niezgodne -> blokuje działanie przycisku');
  28. $("#unblock_UI").submit(function (e) {
  29. e.preventDefault();
  30. e.stopPropagation();
  31. });
  32. }
  33. else {
  34. logoutUser();
  35. }
  36. });
  37. };
[JAVASCRIPT] pobierz, plaintext

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)