ตัวอย่างการใช้งาน AJAX กับเว็บไซต์ ตอนที่ 5
ตัวอย่างนี้จะเป็นตัวอย่างการ Synchronize เวลาด้วย Ajax ซึ่งเป็นประโยชน์ที่สำคัญอีกอย่างของ Ajax
โดยปกติแล้วหากมีการเขียนสคริปต์ที่ต้องมีความเกี่ยวข้องกับเวลา หากใช้เวลาที่มาจาก Javascript ตรงๆ จะเป็นการไม่ปลอดภัยอย่างยิ่ง เนื่องจากเวลาที่ได้มาจาก Javascript สามารถแก้ไขได้ง่ายๆบนบราวเซอร์ เช่นในกรณีที่มีการจับเวลาในการทำข้อสอบ ถ้าผู้ใช้สามารถแก้ไขเวลาได้ก็จะทำให้ผู้ใช้สามารถมีเวลาได้ไม่จำกัดในการทำข้อสอบ ในทางปฏิบัติจึงต้องมีการใช้เวลาที่มาจาก Server โดยเมื่อมีการเริ่มต้นทำข้อสอบให้บันทึกเวลาเก็บไว้ และบันทึกอีกครั้งตอนส่งข้อสอบ เมื่อนำเวลาทั้งสองมาลบกันก็จะได้เวลาที่ใช้ในการทดสอบ
ปัญหาอย่างหนึ่งของวิธีข้างต้นคือผู้ทำข้อสอบจะไม่รู้เวลาที่ตัวเองใช้ไปแล้วในขณะทำข้อสอบเนื่องจากเวลาทั้งหมดอยู่บน Server การแก้ปัญหาเบื้องต้นอาจทำได้โดยการอ่านค่าเวลาเริ่มต้นมาแสดงผลบนบราวเซอร์เสร็จแล้วให้ Javascript เริ่มนับถอยหลังไปจนกว่าจะหมดเวลา
วิธีข้างต้นใช้งานได้ในทางปฎิบัติก็จริง แต่ก็ยังมีปัญหาอีกหลายอย่าง เช่น หากมีการขัดจังหวะโดยผู้ใช้ เครื่องค้าง หรือเกิดเหตุไม่คาดฝันใดๆขึ้นหรือเกิดการรีเฟรช หรือแม้กระทั่งการเปลี่ยนหน้า จะทำให้เราสูญเสียเวลาในทันที ปัญหานี้สามารถแก้ไขได้ด้วยการตรวจสอบเวลาระหว่าง Server และบราวเซอร์ให้ตรงกันอย่างสม่ำเสมอด้วย Ajax
แนวคิดก็ตรงไปตรงมาเลยครับ โดยการใช้ Ajax ส่งข้อมูลกลับไปสอบถามเวลาปัจจุบันจาก Server เป็นระยะๆ เมื่อได้ข้อมูลเวลากลับมาแล้วก็ใช้ข้อมูลนั้นในการปรับเวลาของบราวเซอร์ให้ตรงกับบน Server อีกที
ตัวอย่างนี้เป็นการแสดงเวลาที่ส่งมาจาก Server โดยการใช้ Ajax อ่านเวลามาจาก Server ทุก 1 นาทีเมื่อได้ข้อมูลมาแล้วก็นำเวลาที่ได้ไปแสดงผลทันที เสร็จแล้วให้ Javascript อีกตัววนลูปปรับปรุงเวลาที่แสดงผลทุก 1 วินาที
ส่วนแรกเป็น HTML สำหรับแสดงเวลาเฉยๆไม่มีอะไรซับซ้อนนะครับ สามารถลองแก้ไขเวลาดูได้
Javascript ผมแยกอธิบายออกเป็นสองส่วนนะครับ ส่วนแรกคือการจับเวลาด้วย Javascript
Clock(id, options)
autoupdate เป็นเมธอดหนึ่งของ GAjax มีพารามิเตอร์ 4 ตัวคือ
สุดท้าย Index\Index\Model->time() ซึ่งเป็นคลาสสำหรับรับค่าที่ส่งมาจาก Ajax ซึ่งตัวอย่างนี้ไม่ได้ทำอะไรเลย แค่ส่งเวลาจาก Server กลับไปแสดงผลเท่านั้น
สำหรับคนที่สงสัยว่าทำไมต้องทำแบบนี้ ทำไมไม่อ่านเวลาจาก Server มาใช้งานทีเดียวเลย คำตอบก็คือ การส่งรีเควสไปยัง Server ทุก 1 วินาทีไม่ใช่เป็นสิ่งที่น่าทำนัก โดยเฉพาะหากเป็นการทำข้อสอบ ซึ่งอาจจะมีคนจำนวนมากทำข้อสอบพร้อมๆกันซึ่งการส่งรีเควสพร้อมๆกันไปยัง Server อาจทำให้ Server ล่มได้ เราจึงใช้วิธีการส่งเป็นช่วงๆแทน ซึ่งระยะห่างระหว่างแตละช่วงยิ่งแคบเท่าไร เวลาที่ได้ก็จะแม่นยำมากขึ้น
ตัวอย่างนี้ดูได้ที่นี่นะครับ https://projects.kotchasan.com/...ndex.php?module=time
โดยปกติแล้วหากมีการเขียนสคริปต์ที่ต้องมีความเกี่ยวข้องกับเวลา หากใช้เวลาที่มาจาก Javascript ตรงๆ จะเป็นการไม่ปลอดภัยอย่างยิ่ง เนื่องจากเวลาที่ได้มาจาก Javascript สามารถแก้ไขได้ง่ายๆบนบราวเซอร์ เช่นในกรณีที่มีการจับเวลาในการทำข้อสอบ ถ้าผู้ใช้สามารถแก้ไขเวลาได้ก็จะทำให้ผู้ใช้สามารถมีเวลาได้ไม่จำกัดในการทำข้อสอบ ในทางปฏิบัติจึงต้องมีการใช้เวลาที่มาจาก Server โดยเมื่อมีการเริ่มต้นทำข้อสอบให้บันทึกเวลาเก็บไว้ และบันทึกอีกครั้งตอนส่งข้อสอบ เมื่อนำเวลาทั้งสองมาลบกันก็จะได้เวลาที่ใช้ในการทดสอบ
ปัญหาอย่างหนึ่งของวิธีข้างต้นคือผู้ทำข้อสอบจะไม่รู้เวลาที่ตัวเองใช้ไปแล้วในขณะทำข้อสอบเนื่องจากเวลาทั้งหมดอยู่บน Server การแก้ปัญหาเบื้องต้นอาจทำได้โดยการอ่านค่าเวลาเริ่มต้นมาแสดงผลบนบราวเซอร์เสร็จแล้วให้ Javascript เริ่มนับถอยหลังไปจนกว่าจะหมดเวลา
วิธีข้างต้นใช้งานได้ในทางปฎิบัติก็จริง แต่ก็ยังมีปัญหาอีกหลายอย่าง เช่น หากมีการขัดจังหวะโดยผู้ใช้ เครื่องค้าง หรือเกิดเหตุไม่คาดฝันใดๆขึ้นหรือเกิดการรีเฟรช หรือแม้กระทั่งการเปลี่ยนหน้า จะทำให้เราสูญเสียเวลาในทันที ปัญหานี้สามารถแก้ไขได้ด้วยการตรวจสอบเวลาระหว่าง Server และบราวเซอร์ให้ตรงกันอย่างสม่ำเสมอด้วย Ajax
แนวคิดก็ตรงไปตรงมาเลยครับ โดยการใช้ Ajax ส่งข้อมูลกลับไปสอบถามเวลาปัจจุบันจาก Server เป็นระยะๆ เมื่อได้ข้อมูลเวลากลับมาแล้วก็ใช้ข้อมูลนั้นในการปรับเวลาของบราวเซอร์ให้ตรงกับบน Server อีกที
ตัวอย่างนี้เป็นการแสดงเวลาที่ส่งมาจาก Server โดยการใช้ Ajax อ่านเวลามาจาก Server ทุก 1 นาทีเมื่อได้ข้อมูลมาแล้วก็นำเวลาที่ได้ไปแสดงผลทันที เสร็จแล้วให้ Javascript อีกตัววนลูปปรับปรุงเวลาที่แสดงผลทุก 1 วินาที
ส่วนแรกเป็น HTML สำหรับแสดงเวลาเฉยๆไม่มีอะไรซับซ้อนนะครับ สามารถลองแก้ไขเวลาดูได้
<input type="text" id="demo_txt" value="00:00:00">
Javascript ผมแยกอธิบายออกเป็นสองส่วนนะครับ ส่วนแรกคือการจับเวลาด้วย Javascript
// เริ่มต้นจับเวลาด้วย Javascript
new Clock('demo_txt');
Clock(id, options)
- id (string) ชื่อไอดีของ element ที่แสดงเวลา
- options (Object) ค่าพารามิเตอร์ที่ส่งให้กับ Clock มีแค่ 2 ตัว
- reverse (boolean) ค่าเริ่มต้นคือ false หมายถึงเป็นนการนับเดินหน้าตามปกติ เช่นการแสดงเวลา หรือ true จะทำให้ Clock นับเวลาถอยหลัง เช่นการใช้เป็นนาฬิกาจับเวลา
- onTimer (function) เป็นฟังก์ชั่นเหตุการณ์เมื่อมีการจับเวลา ซึ่งจะเกิดขึ้นทุกวินาทีตามที่ Clock ทำงาน มีพารามิเตอร์อีก 3 ตัว คืนค่าเวลาปัจจุบันคือ function(Hour, Minute, Second) {...}
// ฟังก์ชั่น Ajax อ่านข้อมูลจาก Server เป็นระยะ
new GAjax().initLoading('demo_txt').autoupdate('index.php/index/model/index/time', 60, null, function (xhr) {
$E('demo_txt').value = xhr.responseText;
});
autoupdate เป็นเมธอดหนึ่งของ GAjax มีพารามิเตอร์ 4 ตัวคือ
- url (string) เป็น URL ที่ Ajax ใช้ร้องขอข้อมูล โดยทั่วๆไปสำหรับคชสารจะเป็น Model เช่น http://domain.tld/...ndex/model/ajax/post หมายถึงเรียกไปยัง Index\Ajax\Model->post() เป็นต้น
- interval (int) ช่วงเวลาที่ใช้ในการอัปเดท หน่วยเป็นวินาที
- getRequest (function) ฟังก์ชั่นสำหรับอ่านค่าพารามิเตอร์ที่ต้องการส่งไปด้วย Ajax รูปแบบ Query String ถ้าไม่มีพารามิเตอร์ส่งไปให้ระบุ null
- callback (function) เป็นฟังก์ชั่นสำหรับรับค่าที่ส่งกลับมาจาก Ajax โดยจะมีพารามิเตอร์ส่งกลับมาด้วยเป็น XHR Object ตัวอย่าง function(xhr) {...}
สุดท้าย Index\Index\Model->time() ซึ่งเป็นคลาสสำหรับรับค่าที่ส่งมาจาก Ajax ซึ่งตัวอย่างนี้ไม่ได้ทำอะไรเลย แค่ส่งเวลาจาก Server กลับไปแสดงผลเท่านั้น
/**
* อ่านเวลาจาก Server
*
* @param Request $request
*/
public function time(Request $request)
{
// คืนค่าเวลาปัจจุบันจาก Server
echo date('H:i:s');
}
สำหรับคนที่สงสัยว่าทำไมต้องทำแบบนี้ ทำไมไม่อ่านเวลาจาก Server มาใช้งานทีเดียวเลย คำตอบก็คือ การส่งรีเควสไปยัง Server ทุก 1 วินาทีไม่ใช่เป็นสิ่งที่น่าทำนัก โดยเฉพาะหากเป็นการทำข้อสอบ ซึ่งอาจจะมีคนจำนวนมากทำข้อสอบพร้อมๆกันซึ่งการส่งรีเควสพร้อมๆกันไปยัง Server อาจทำให้ Server ล่มได้ เราจึงใช้วิธีการส่งเป็นช่วงๆแทน ซึ่งระยะห่างระหว่างแตละช่วงยิ่งแคบเท่าไร เวลาที่ได้ก็จะแม่นยำมากขึ้น
ตัวอย่างนี้ดูได้ที่นี่นะครับ https://projects.kotchasan.com/...ndex.php?module=time