• 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

Object Storage Arubacloud
+1 głos
237 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 (253,340 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ź 311 wizyt
pytanie zadane 10 lutego 2016 w JavaScript przez CzlowiekSkrypt Nałogowiec (26,340 p.)
0 głosów
1 odpowiedź 403 wizyt
0 głosów
0 odpowiedzi 209 wizyt
pytanie zadane 17 marca 2018 w JavaScript przez Honter Użytkownik (690 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...