• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Logowanie i obliczanie progresji wykonania skryptu PHP wywołanego przez AJAX

VPS Starter Arubacloud
+1 głos
260 wizyt
pytanie zadane 2 czerwca 2021 w JavaScript przez sc4rface Dyskutant (7,710 p.)

Cześć wam, próbuję napisać rozwiązanie, które wyśle żądanie AJAX do pliku PHP, na bieżąco pobierze postęp jego wykonywania (dla wyświetlenia paska postępu) oraz wyświetli we front-endzie wszystkie wiadomości zwrotne przez ten skrypt dostarczane (czyli wszystko co echowane).

Moje rozwiązanie działa połowicznie z dwóch względów, mianowicie:

1. Wiadomości duplikują, a dokładniej "stackują" się, zamiast wyświetlać każdą po kolei. Nadmienię, że zamiast filtracji po stronie klienta chciałbym wyeliminować błąd już na etapie backendu. Wygląda to w ten sposób:

Set up...

Set up... Analyzing...

Set up... Analyzing... Exit

A powinno tak:

Set up...

Analyzing,..

Exit

Nadmienię, że każdy kolejny string jest dopisywany do poprzedniego, nie są to osobne ciągi, stąd porównywanie poprzedniego z aktualnym nie zadziała.

2. Nie mogę obliczyć dokładnego progresu dla paska ze względu na brak parametru e.total z racji używania flush() i ob_flush(), ponieważ bufor jest czyszczony i ta wartość zawsze wynosi 0

$('#import').on('submit', function(e) {

  e.preventDefault();

  $.ajax({
    url: $(this).prop('action'),
    method: $(this).prop('method'),
    xhrFields: {
      onprogress: function(e) {
        $('#logs').append('<p>' + e.target.responseText + '</p>');
        $('progress').val((e.loaded / e.total) * 100);
      }
    },
    success: function(response) {
      console.log(response);
    }
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="import" method="POST" action="import.php">
  <div id="logs"></div>
  <progress max="100" value="0"></progress>
  <button type="submit">Run</button>
</form>

Plik import.php dla celów testowych do którego odwołuje się formularz.

echo 'Set up...';
ob_flush();
flush();
sleep(1);
    
echo 'Analyzing...';
ob_flush();
flush();
sleep(1);
    
echo 'Exit';
ob_flush();
flush();
sleep(1);

1 odpowiedź

0 głosów
odpowiedź 3 czerwca 2021 przez VBService Ekspert (255,840 p.)
wybrane 4 czerwca 2021 przez sc4rface
 
Najlepsza

Propozycja do punktu 1-go

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="import" method="POST" action="import.php">
  <div id="logs" data-last-text-ajax=""></div>
  <progress max="100" value="0"></progress>
  <button type="submit">Run</button>
</form>

<script>
$('#import').on('submit', function(e) {
 
  e.preventDefault();
 
  $.ajax({
    url: $(this).prop('action'),
    method: $(this).prop('method'),
    xhrFields: {
      onprogress: function(e) {
        const text = e.target.responseText.replace($('#logs').attr('data-last-text-ajax'), '');
        $('#logs').attr('data-last-text-ajax', e.target.responseText);

        $('#logs').append('<p>' + text + '</p>');
        $('progress').val((e.loaded / e.total) * 100);
      }
    },
    success: function(response) {
      console.log(response);
    }
  });
 
});

</script>

 

Poniżej na obrazku, kod ajax-a uruchomiony przez 3 krotne kliknięcie przycisku Run  wink

 

Propozycja dla 2-go punktu (przy założeniu, że wszystkich znaków wysłanych ze skryptu php nie będzie więcej niż 100)

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form id="import" method="POST" action="import.php">
  <div id="logs" data-last-text-ajax=""></div>
  <progress max="100" value="0"></progress>
  <button type="submit">Run</button>
</form>

<script>
$('#import').on('submit', function(e) {
 
  e.preventDefault();

  if ($('progress').val() > 99) {
    $('#logs').html('');
  }
 
  $('button[type="submit"]').attr('disabled', true);

  $.ajax({
    url: $(this).prop('action'),
    method: $(this).prop('method'),
    xhrFields: {
      onprogress: function(e) {
        const text = e.target.responseText.replace($('#logs').attr('data-last-text-ajax'), '');
        $('#logs').attr('data-last-text-ajax', e.target.responseText);

        $('#logs').append('<p>' + text + '</p>');
        $('progress').val(e.loaded);
      }
    },
    success: function(response) {
      console.log(response);
      $('button[type="submit"]').attr('disabled', false);
    }
  });
 
});
</script>

import.php

<?php

$status_message = ['Set up...', 'Analyzing...', 'Exit'];
$status_message_progress = 100 / count($status_message);

foreach ($status_message as $index => $message) {
  echo $message;
  echo str_repeat(' ', ($status_message_progress - strlen($message)));

  switch ($index) {
    case 0: // Set up...
      // kod dla set up-a
      break;
    case 1: // Analyzing...
      // kod dla analyzing
      break;
    case 2: // Exit
    default:
      // kod dla exit
      echo str_repeat(' ', (100 % count($status_message)));
  }

  ob_flush();
  flush();
  sleep(1);
}

?>

Podobne pytania

0 głosów
1 odpowiedź 363 wizyt
pytanie zadane 10 lutego 2016 w JavaScript przez CzlowiekSkrypt Nałogowiec (26,340 p.)
0 głosów
1 odpowiedź 632 wizyt
0 głosów
0 odpowiedzi 218 wizyt
pytanie zadane 17 marca 2018 w JavaScript przez Honter Użytkownik (690 p.)

93,015 zapytań

141,978 odpowiedzi

321,271 komentarzy

62,358 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...