บทความนี้ต่อจาก Ajax คืออะไร แล้วมันใช้ยังไง? - ตอนที่ 1 ภาคทฤษฎี ใครยังไม่อ่านและไม่ค่อยเข้าใจว่า Ajax มีไว้ทำไม ลองกลับไปทำความเข้าใจดูก่อนนะ
Ajax in Action! มาดูการเขียนโค้ดใช้จริงกันบ้างดีกว่า
ความจริงสิ่งที่ JavaScript ทำไม่ได้หลักๆ (ซึ่งมันสำคัญมากสำหรับโปรแกรม) คือ
มันไม่มีความสามารถในการเชื่อมต่อ Database
เพราะว่า Database นั้นส่วนใหญ่เก็บอยู่ในฝั่ง Server ส่วนเจ้าตัว JavaScript นั้นเป็นภาษาที่รันในฝั่ง Client
ใครที่ไม่รู้จัก Server vs Client ให้กลับไปอ่านที่ Intro JavaScript ก่อนนะ
ตัวอย่างของการใช้ Ajax ที่เห็นบ่อยๆ เช่น
paging ลิงค์ไปหน้าต่อไป
การทำเพจจิ้งหนา้ตัวเลขพวกที่เราเห็นเวลาเล่นเว็บบอร์ดเช่น ไปหน้า 1 2 3 ... พวกนี้ เวลาเรากด (สำหรับเว็บที่ไม่ได้ใช้ Ajax ซึ่งก็คือเว็บส่วนใหญ่ที่พบเห็นได้ในไทย) จะใช้การส่ง "Query String" ซึ่งเป็นค่าตัวแปรพ่วงต่อท้าย url ไปเช่น
www.nainee.com/board/view?id=100 www.nainee.com/board/view?id=200 www.nainee.com/board/view?id=300
ค่าพวกนี้ ส่วนใหญ่ใช้สำหรับเอาไปดึงค่าออกมาจาก Database เช่น
select * from Topics limit $id, 100
ตัวเลขที่ส่งพ่วงหลัง url ไปนั่นก็เพื่อให้รู้ว่าต้องดึงข้อมูลตั้งแต่ตัวไหนออกมาแสดง
ในระหว่างคลิกไปหน้าต่อไป จะต้องมีช่วงที่ Browser ส่ง request ไปหา Server เพื่อขอหน้าเพจที่ต้องการ ซึ่งมันจะกลายเป็นขาวๆ แป๊ปนึง |
มาดูวิธีการใช้ Ajax กันบ้าง
นึกถึงเวลาเล่น Facebook ถ้าเราสกอร์เมาส์ลงมาอ่านสเตตัสเพื่อนๆ เรื่อยๆ แล้วมันโผล่ปุ่มให้กดอ่านในหน้าต่อไปมันก็คงแปลกๆ และไม่น่าใช้เท่าเวลาที่สกอร์เมาส์ลงไปเรื่อยๆ แล้วมีเนื้อหาชุดต่อไปโผล่มาต่อๆๆ ไปให้เลยใช่ป่ะ
ซ้ายคือแบบปกติ โหลดหน้าเพจขึ้นมาครั้งหนึ่ง แล้วถ้าจะดูเพิ่มก็ต้องกดดูหน้าต่อไปขวาคือแบบใช้ Ajax ทำการโหลดข้อมูลมาเพิ่มเรื่อยๆ ทำให้เราอ่านต่อไปไม่ต้องกดโหลดใหม่ |
คำถามคือ แล้วมันทำยังไงล่ะ JavaScript ธรรมดาๆ ถึงสามารถดึงข้อมูลชุดอื่นๆ จากใน Database มาแสดงได้?
ความจริงแล้วคนที่ดึงข้อมูลจาก Database ออกมาน่ะ ไม่ใช่ JavaScript หรอก แต่เป็นภาษาฝั่งเซิร์ฟเวอร์เช่น PHP ตั้งหาก
JavaScript จะเรียกผู้ช่วยตัวนึงขึ้นมา (สมมุติเรียกว่า X-Engine) แล้วบอกว่า
- "เฮ้ ฉันต้องการข้อมูลเพิ่มจาก Database" ... เสร็จแล้ว JavaScript ก็บอกไว้ว่าถ้าได้ข้อมูลที่มันต้องการกลับมาแล้วน่ะ มาบอกมันด้วยนะ (การโหลดต้องใช้เวลา ขี้เกียจรอ)
- เจ้า X-Engine ตัวนี้ก็จะรับหน้าที่วิ่งไปหาเซิร์ฟเวอร์แล้วถาม PHP ต่ออีกทีว่า
"เฮ้ ฉันต้องการข้อมูลเพิ่มจาก Database (เพราะมีคนฝากขอมา)" - เมื่อ PHP ได้ฟัง (รับ request แล้ว) ก็ทำการเชื่อมต่อ Database ซึ่งมันทำได้อยู่แล้ว
- ... // รอสักครู่ PHP กำลังดึงข้อมูลออกมาให้ // ...
- ในตอนนี้ PHP ดึงข้อมูลชุดใหม่ออกมาให้แล้ว ก็ส่งมันต่อให้ X-Engine ผู้ช่วยของเรา (อันนี้คือการ response)
- เมื่อ X-Engine ได้ข้อมูลที่เราฝากมันไปขอมาแล้ว มันก็จะวิ่งกลับมาแล้วสะกิดเรียก JavaScript เพื่อบอกว่า
"ข้อมูลที่แกฝากให้ไปเอา ได้มาแล้วนะ อยู่นี่ๆ"
มาลองเขียนโค้ดกันดู
ในตอนต้นของบล๊อกเราบอกไปว่า Ajax คือการสร้างผู้ช่วยขึ้นมาคนหนึ่ง ซึ่ง
JavaScript มีไว้อยู่แล้วเป็น buildin-Object ซึ่งมันมีนามว่า
XMLHttpRequest
ส่วนเวลาจะใช้ก็...
var xmlhttp = new XMLHttpRequest();
ต้องสร้างเจ้าผู้ช่วย (หรือ X-Engine ที่พูดไปข้างต้น) ขึ้นมาก่อน
*หมายเหตุ สำหรับผู้ที่ใช้ หรือต้องเขียนเว็บให้กับลูกค้าที่ใช้ IE6 ขอแสดงความยินดีด้วยที่เจ้า IE6 นั้นมันไม่มี XMLHttpRequest ให้คุณ แต่คุณสามารถไปเรียกใช้มันได้จาก
ActiveXObject("Microsoft.XMLHTTP");
ซึ่งเราจะไม่ขอพูดถึงมัน (ฮา) ... ผู้เขียนขอสนับสนุนการเลิกใช้ IE นะ เพราะมันทำให้เว็บโปรแกรมเมอร์ปวดหัวกับมันมานักต่อนัก
สำหรับการใช้งานเราจะแบ่งมันออกเป็นช่วงหลักๆ 2 ช่วงนั่นคือ
- สร้างชุดโค้ดสำหรับบอกว่า ถ้ามันไปดึงข้อมูลจากเซิร์ปเวอร์กลับมาเรียบร้อย เราจะสั่งให้โค้ดชุดนี้ทำงาน
- สั่งให้ XMLHttpRequest ทำการส่งคำขอข้อมูลไปยังฝั่งเซิร์ฟเวอร์
สร้างตัวรันเมื่อเซิร์ฟเวอร์ตอบกลับมา
สำหรับชุดโค้ดที่ต้องเตรียมไว้สำหรับรันตอนที่เซิร์ฟเวอร์ตอบกลับมาแล้วเขียนอย่างนี้
xmlhttp.onreadystatechange = function() { //TODO }
บอก XMLHttpRequest ว่าเมื่อ "state" มีการเปลี่ยนแปลงให้รันฟังก์ชั่นต่อไปนี้เลยนะ
แล้วอะไรคือ state ?
- 0 : request not initialized (คำขอยังไม่ถูกสั่ง)
- 1 : server connection established (เริ่มเชื่อมต่อเซิร์ปเวอร์)
- 2 : request received (คำขอได้รับแล้ว)
- 3 : processing request (เซิร์ฟเวอร์กำลังทำงาน รอแป๊ปนะ)
- 4 : request finished and response is ready (เซิร์ฟเวอร์ทำงานเสร็จแล้ว และตอบอะไรบางอย่างกลับมา)
สเตจก็คือตัวที่บอกให้รู้ว่าตอนนี้ XMLHttpRequest ทำงานไปถึงไหนยังไงบ้างแล้ว โดยจะใช้แทนด้วยตัวเลข 0 ถึง 4 ตามที่เขียนไว้ข้างบน
ดังนั้นฟังก์ชั่น onreadystatechange ก็จะทำงานตามชื่อมันซึ่งก็คือทุกครั้งที่สเตจมีการเปลี่ยนแปลง แต่เดี๋ยวก่อน!
เราต้องการให้ฟังก์ชั่นนี้ทำงานเฉพาะตอนที่เซิร์ฟเวอร์ตอบกลับมาแล้วเท่านั้น (สเตจที่4) เราเลยต้องเพิ่มเงื่อนไขเข้าไปว่า
xmlhttp.onreadystatechange = function() { if(xmlhttp.readyState == 4){ //TODO } }
สั่งให้ทำงานเมื่อสเตจในรอบนั้นเป็น 4 เท่านั้น (คือเซิร์ฟเวอร์ตอบกลับมาเรียบร้อย)
แต่แค่นั้นก็ยังไม่จบนะ (ยังไม่พออีกเหรอ? O_O )
นอกจากสเตจที่ต้องเช็กแล้วก็ยังมีอีกอย่างนั่นคือ "status" ซึ่งเป็นตัวบอกว่าการขอข้อมูลของเรานั่นสำเร็จหรือไม่
มันต่างกันนะ อย่าคิดว่ามันคือตัวเดียวกับ state ล่ะ
- state เป็นตัวบอกว่าตอนนี้กำลังเชื่อมต่อเซิร์ฟเวอร์ -> เซิร์ฟเวอร์รับคำขอข้อมูลไปแล้ว -> เซิร์ฟเวอร์กำลังคิดนะจ๊ะ -> เซิร์ฟเวอร์ตอบกลับมาแล้ว เย้!
- status เป็นตัวที่บอกว่าคำขอข้อมูลนั้นน่ะมันใช้ได้รึเปล่าเพราะบางทีเซิร์ฟเวอร์ตอบกลับมาก็จริง แต่ตอบกลับมาไม่ใช่ในสิ่งที่เราต้องการ
ตัวอย่างเช่นเวลาเราเรียก url ที่ไม่มีอยู่จริง เซิร์ฟเวอร์ก็จะตอบกลับมาว่า Page not found! ซึ่งบางครั้งจะมีตัวห้อยเลขรหัสว่า 404 กลับมาด้วย
อืม คิดว่าหน้าที่คุณเรียกน่ะมัน... |
ดังนั้นเราต้องเช็กว่าหน้าเพจ (ข้อมูลที่เราต้องการ) มันตอบกลับมาเป็นสิ่งที่เราจะเอา ไม่ใช่ตอบเจ้า 404 นี่กลับมา
ตัวเลขแสดงผลของ status หลักๆ จะมีสองตัวคือ
- 200 : "ok" ผลแบบนี้ถือว่าใช้ได้
- 404 : Page Not Found ถ้าตอบกลับมาแบบนี้ก็มีปัญหาอะไรสักอย่างนึงแล้วล่ะ เช่นอาจจะเขียน url ผิดเป็นต้น
สรุป...
xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { alert( xmlhttp.responseText ); } }
ก็เช็กซะทั้งสองค่าว่ามันเป็นทั้งสเตจที่เซิร์ฟเวอร์ตอบกลับมาแล้ว และยังตอบกลับมาถูกต้องอีกด้วย
สำหรับค่าที่เซิร์ฟเวอร์ตอบกลับมาจะอยู่ในตัวแปรที่ชื่อว่า xmlhttp.responseText เราสามารถเอามันไปใช้อะไรต่อก็ได้
ส่งคำขอไปหาเซิร์ฟเวอร์
หลังจากเราสร้างฟังก์ชั่นชุดที่จะเอาไว้รันตอบเซิร์ฟเวอร์ตอบกลับมาไปแล้ว เราก็จะทำการส่งคำขอไปหาเซิร์ฟเวอร์
ในขั้นนี้เราต้องเลือกว่าเราจะส่งด้วย method แบบไหน GET หรือ POST ?
(จะขอยกตัวอย่างแบบ GET เพียงตัวเดียว)
xmlhttp.open("GET","serv.php"); xmlhttp.send();
ใช้โค้ดแบบข้างบนเพื่อส่งคำขอไปหาเซิร์ฟเวอร์ อย่างในตัวอย่างจะส่งไปหาเซิร์ฟเวอร์ที่หน้า serv.php
สมมุติว่าในหน้า serv.php มีสคริปเขียนไว้ดังนี้
<?php echo "ทดสอบนะๆ";
หลังจากสั่ง send() ไปเรียบร้อย เมื่อใดก็ตามที่เซิร์ฟเวอร์ตอบกลับมา คำว่า ทดสอบนะๆ ก็จะถูกส่งไปให้โค้ดส่วนที่เราเตรียมไว้ตอนแรกผ่านตัวแปร xmlhttp.responseText เลย
*หมายเหตุ เนื่องจากในปัจจุบัน คนส่วนใหญ่ไม่ค่อยเขียนโค้ดด้วยสคริปมาตราฐาน (มันเก่ามาก) แบบนี้กัน แล้วหันไปใช้ Library JavaScript เช่น jQuery กันหมดแล้ว เลยจะไม่ขอยกตัวอย่าง workshop ด้วยการเขียนแบบนี้ แต่จะยกตัวอย่างวิธีการใช้งานเต็มๆ ในบล๊อกหน้า "การใช้งาน Ajax ด้วย jQuery" แทนไปเลย
อ่านตอนสามต่อได้ที่ Ajax คืออะไร แล้วมันใช้ยังไง? – ตอนที่ 3 ภาคปฏิบัติ (ใช้ jQuery)