Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [JS] Redirect po ajax request niszczy ten request?
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
iwosz
Cześć,

Specyfikacja środowiska:
PHP 5.3.x przez FastCGI (config standardowy)
IIS 7.5 (standardowe ustawienia)

Mam dziwną sytuację i zastanawiam się cy ja to dobrze rozumiem.

Wykonuję AJAX request który uruchamia funkcję PHP która z kolei zapisuje konkretną daną do sesji (wykonanie funkcji trwa kilka sekund). W skrypcie JS funkcja nie czeka na zakończenie tego requesta tylko wykonuje od razu redirect (window.location = url). Gdy już strona WWW się przeładuje wyświetlam sobie tą zmienną zapisaną w sesji i niestety wartość jest pusta. Pseudo-kod dla jasności:

Po stronie przeglądarki w jQuery:
  1. function saveToSession() {
  2. $.ajax({
  3. type: "POST",
  4. url: 'session.php',
  5. data: 'action=saveValToSession'
  6. success: function(response){ nic sie tutaj nie dzieje, nie czekamy na wynik }
  7. });
  8. window.location = 'index.php';
  9. }


Po stronie serwera plik session.php:
  1.  
  2. if( $_REQUEST['action'] == 'saveValToSession' ) {
  3. $_SESSION['val'] = 'przykladowa wartosc';
  4. }

Po przeładowaniu strony zmienna 'val' nie istnieje w sesji.

Pytanie co się stało?

1. Czy wykonując request AJAX na serwer, raz wywołana funkcja PHP w ten sposób powinna poprawnie się zakończyć?
2. Czy wykonanie redirecta anulowało AJAX request? Tzn. serwer WWW stwierdził że użytkownik nie jest już zainteresowany odpowiedzią i zakończył żądanie? Ale przecież już wywołana funkcja w PHP powinna się dokończyć mimo wszystko?
3. Czy redirect spowodował zabicie poprzednio używanego procesu PHP i stworzenie nowego?

UWAGA: jeśli zakomentuję redirecta i poczekam na odpowiedź requesta AJAX wartość zapisuje się poprawnie w sesji! smile.gif

Mógł by mi to ktoś wytłumaczyć? businesssmiley.png
devnul
google -> php ignore_user_abort
iwosz
devnul dzięki, z tego co przeczytałem to powinno rozwiązać problem. Ustawiłem "ignore_user_abort = On" w php.ini jednak nic to nie dało. Jeszcze z tym powalczę i napisze jak uda mi się rozwiązać ten problem.

edit--

W php.ini ustawienie "ignore_user_abort = On" nic nie dało, dodam że max_execution_time jest na 100% wystarczający.
W pliku PHP dodanie na samym początku:

nie dało żadnego rezultatu (logiczne skoro w php.ini nic nie dało to tym bardziej lokalne ustawienie nic nie da)
W php.ini tryb bezpieczny jest wyłączony.

Czy jest możliwe aby redirect anulował request AJAX zanim on dotrze do serwera?

edit2--

Jak robię redirecta z opóźnieniem kilka sek. to działa, tzn. request AJAX w ogóle jest wysłany na serwer. Dalej już PHP zachowuje się tak jak mówi opis ustawienia "ignore_user_abort", czyli funkcja poprawnie dokręca się do końca.
IProSoft
Wrzuć na początku pliku PHP:
  1. <?php
iwosz
To mam teraz inne pytanie, a nie chcę nowego tematu zakładać (pytanie dotyczy PHP).

Jak już powyżej opisałem, wykonuję request AJAX który wywołuje funkcję PHP która pobiera dane i zapisuje do sesji, to trwa dość długo i chciał bym aby wykonywało się w tle tak żeby użytkownik nie musiał czekać. Dlatego nie czekam na wynik tego requesta tylko wykonuję redirect (alternatywnie )

Obecnie request dociera do serwera i po ustawieniu "ignore_user_abort = On" funckja PHP wykonuje się do końca poprawnie, ale nadal długo.. zatem co się dzieje gdy użytkownik w tym czasie stwierdzi że chce zapytać inny plik PHP? PHP będzie czekał na zakończenie wykonywanej funkcji i tu się pojawia problem, bo chodzi o to aby użytkownik mógł w pełni korzystać z systemu w czasie wykonywania tej funkcji.

Tutaj nasuwa się pomysł ręcznego utworzenia nowego procesu PHP(pcntl_fork) dedykowanego do wykonania tej funkcji. Problem pojawia się przy przekazywaniu danych do sesji, bo jak wiadomo każdy proces ma swoją część pamięci i między sobą nie wymieniają się informacjami jakie dane aktualnie posiadają. W takim wypadku nowy process musiał by zapisywać wynik operacji np. do pliku lub bazy danych. To nawet nie jest głupie gdy z tych samych danych korzysta wielu użytkowników, wtedy process mógł by być wywoływany przez Windows Scheduler np. co godzinne i aktualizować dane w bazie danych. Wtedy użytkownik logując się do aplikacji miał by już relatywnie aktualny zestaw danych do dyspozycji bez konieczności wykonywania funkcji PHP.

Jest to zupełne odejście od mojej pierwotnej koncepcji, może ma ktoś lepszy pomysł?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.