ป้ายกำกับ: AJAX

jQuery: Ajax รับข้อมูลแบบ streamjQuery: Ajax รับข้อมูลแบบ stream

บางงานต้องใช้เวลาในการทำงาน ถ้าปล่อยให้ user รออย่างเดียวก็จะกังวลว่ามันจะทำงานสำเร็จหรือมี error รึเปล่า เคยเขียนวิธี jQuery Ajax แบบอนุกรมตามลำดับ ไว้ แต่อาจจะไม่เหมาะถ้า task บางอย่างมันยาวนานกว่านั้น ถึงลองเขียนแบบ flush stream / streaming ดู

ตัวจำลองเวลาโหลดโดยสุ่มถ่วงเวลาให้เหมือนจริง

<?php

set_time_limit(0);

header('Cache-Control: no-cache');
header('Content-Type: text/event-stream');

function task($ad, $message, $progress = '')
{
 $data = [
  'id' => $ad,
  'message' => $message,
  'progress' => $progress,
 ];

 echo json_encode($data);

 ob_flush();
 flush();
}

/* loop processing */
for ($a = 1; $a <= 10; $a++) {
 task($a, 'on iteration ' . $a . ' of 10', $a * 10);

 sleep(rand(1, 10));
}

task('CLOSE', 'Process complete');

ตัวอย่างการใช้ jQuery.ajax()

<!DOCTYPE>
<html>

<head>
 <title>Flushed ajax test</title>
 <meta charset="UTF-8" />
 <style>
  #results {
   background: #eee;
   border: 1px solid #c00000;
   height: 250px;
   overflow: auto;
   padding: 10px;
   width: 98%;
  }
 </style>
</head>

<body>
 <div id="results" style=""></div>
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
 <script>
  var last_response_len = false;
  $.ajax('stream.php', {
    xhrFields: {
     onprogress: function(e) {
      var this_response, response = e.currentTarget.response;
      if (last_response_len === false) {
       this_response = response;
       last_response_len = response.length;
      } else {
       this_response = response.substring(last_response_len);
       last_response_len = response.length;
      }
      console.log(this_response);
      data = $.parseJSON(this_response);
      console.log(data);
      $('#results').append('<br>' + data.message);
     }
    }
   })
   .done(function(data) {
    console.log('Complete response = ' + data);
    $('#results').append('<br><br>Complete response = ' + data);
   })
   .fail(function(data) {
    console.log('Error: ', data);
   });
  console.log('Request Sent');
 </script>
</body>

</html>

ถ้าดูใน console.log จะเห็นว่าตัวแปร data มันจะโดนเพิ่มขึ้นมาเรื่อง ๆ ดังนั้นถ้ามี response มาจาก server เยอะ ๆ ก็ต้องแก้ไข code ด้วย

update วิธีเขียนให้ง่ายขึ้นและทำงานบน nginx ได้ ตามที่เขียนใน NGINX: แสดงผลลัพธ์ทันที

<?php

set_time_limit(0);

header('Cache-Control: no-cache');
header('Content-Type: text/event-stream');
header('X-Accel-Buffering: no');

set_time_limit(0);

ob_implicit_flush(true);
ob_end_flush();

function task($ad, $message, $progress = '')
{
 $data = [
  'id' => $ad,
  'message' => $message,
  'progress' => $progress,
 ];

 echo json_encode($data);
}

/* loop processing */
for ($a = 1; $a <= 10; $a++) {
 task($a, 'on iteration ' . $a . ' of 10', $a * 10);

 sleep(rand(1, 10));
}

task('CLOSE', 'Process complete');