เกริ่นนำ
ปัจจุบันนักพัฒนามีความนิยมใช้งาน AJAX อย่างแพร่หลายเนื่องจาก AJAX ช่วยให้การทำงานของ Web App มีประสิทธิภาพมากขึ้น จำเป็นที่จะต้องแยกส่วนที่เป็น Front-End และ Back-End อิสระออกจากกัน ซึ่งหมายความว่าอาจจะแยกกันอยู่คนละ Hosting และ มี Domain ที่แตกต่างกัน
ตัวอย่าง Code PHP เพื่อรับค่าเวลาจาก Server
<?php
date_default_timezone_set('Asia/Bangkok');
$datetime = date('d-M-Y');
$json = json_encode($datetime);
echo $json;
ตัวอย่าง Code jQuery
$.ajax({
type: 'GET',
url: 'http://api.myapp.com',
dataType: 'json',
success: function(data) {
console.log(data);
}
});
แต่หากเรามีความต้องการ ที่จะ Host ส่วนที่เป็น Web API (REST API) และส่วนที่เป็น Web App อิสระออกจากกันโดยการ Host ไว้คนละโดเมน เช่น
- Web App: http://www.myapp.com
- Web API: http://api.myapp.com
เมื่อเรียกใช้งาน AJAX ตาม Coding ข้างต้น ก็จะเจอข้อความ Error ประมาณนี้ครับ
XMLHttpRequest cannot load http://api.myapp.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.myapp.com' is therefore not allowed access.
ทัั้งนี้เพราะ Web Browser ต้องรักษา Same-Origin Policy (SOP) ซึ่งเป็นหลักการด้านความปลอดภัย โดย Web Browser อนุญาตให้ส่ง AJAX Request ไปยัง Server ได้ แต่จะไม่ยอมให้รับข้อมูลที่ถูกส่งกลับมา (JSON)
Same-Origin Policy (SOP)
SOP จะถูกกำหนดด้วยข้อกำหนด 3 ข้อคือ
- Protocol เช่น HTTP, HTTPS
- Host เช่น www.myapp.com, api.myapp.com
- Port เช่น 80, 8080
ดังนั้นไม่เพียงแค่ Host เท่านั้น แต่หาก Origin และ Destination มีข้อใดข้อหนึ่งใน 3 ข้อ นี้แตกต่างกัน ก็จะเข้าข่ายละเมิด SOP และจะส่งผลให้เกิด Error ตามตัวอย่างข้างต้น
การแก้ไข
จากการค้นหาใน Google นั้นเจอวิธีการแก้ไขปัญหาดังกล่าวประมาณ 3-4 วิธี แต่ผู้เขียนจะขอเลือกมา 2 วิธีซึ่งเป็นวิธีที่ใช้ได้ผลและไม่ยุ่งยากสำหรับนักพัฒนาคือ
- การแก้ไข HTTP Header
- การใช้ JSON-P
การแก้ไข HTTP Header
สำหรับวิธีนี้ เราสามารถใช้ Code jQuery ในรูปแบบเดิม เพียงแต่มีการเพิ่ม function header
ในส่วนของ Server Side ก่อนทำการ echo ตัวแปรแบบ JSON ดังนี้
ตัวอย่าง Code PHP
header('Access-Control-Allow-Origin: http://www.myapp.com');
echo $json;
เพียงเท่านี้ก๋จะสามารถ ใช้งาน AJAX ข้ามโดมเมนได้แล้ว
การใช้ JSON-P
เนื่องจากวิธีการแรกอาจจะไม่ Compatible กับ Web Browser Internet Explorer เวอร์ชั่น 7 และ 8 ผู้เขียนจึงขอเสนอวิธีการสำรองคือการใช้ JSON-P (JSON with Padding) ซึ่งออกแบบมาสำหรับ การใช้งานแบบ Cross Domain ซึ่งเมื่อมีการส่ง AJAX Request แบบ JSON-P ฝั่ง Server จะทำการส่ง JavaScript Block ที่ห่อหุ้ม JSON อยู่ด้านในอีกที
อย่างไรก็ตามข้อเสียของ JSON-P คือรองรับเฉพาะการส่ง AJAX Request แบบ GET เพียงเท่านั้น
ตัวอย่าง Code PHP
if(isset ($_GET['callback'])) {
header('Content-Type: application/javascript');
echo $_GET['callback'] . '(' . $json . ');';
}
ตัวอย่าง Code jQuery
$.ajax({
type: 'GET',
url: 'http://api.myapp.com',
dataType: 'jsonp',
success: function(data) {
console.log(data);
}
});
บทสรุป
สำหรับการใช้งาน AJAX แบบ Cross Domain ในแบบ POST หรือ HTTP Verb แบบอื่นๆ กับ Web Browser เวอร์ชั่นเก่า สามารถใช้วิธีแบบ Proxy ซึ่งไม่ได้คลอบคลุมในเนื้อหาของบทความนี้ครับ
ไม่มีความคิดเห็น:
แสดงความคิดเห็น