การส่งค่า AJAX ไปยัง server side script ที่อยู่คนละโดเมนกับไฟล์ที่รีเควสท์ browser ต่างๆ จะไม่อนุญาติให้ทำเนื่องจากเหตุผลทางด้าน security
โดยทั่วไปจะแก้ปัญหาใช้วิธีรีเควสท์ AJAX ผ่านทาง Proxy แต่วิธีนี้ต้องใช้คำสั่งจำพวก
open remote file ถ้าใช้เว็บโฮสฟรีก็หมดสิทธิใช้คำสั่งพวกนี้เพราะมักจะถูกกันเอาไว้ไม่ให้ใช้
แต่มีอีกทางเลือกหนึ่งเป็นเทคนิคในการแทรก script tag ลงไปพร้อมกับตั้ง src ให้เป็น url ของไฟล์ที่มีฟอร์แมท JSONP
ทำให้เราสามารถเอาข้อมูลมาใช้งานได้เลย
ฟอร์แมทของ JSONP สรุปง่ายๆ เลยก็คือเป็น statement ของการ call function ธรรมดาๆ นี่เอง
โดยมี agument อยู่ในรูปแบบ JSON
เช่น callbackfunction({"name":"hello world"}); เป็นการส่ง argument
ไปให้กับ function ที่ชื่อว่า callbackfunction ดังนั้นเมื่อเราสร้าง function ที่ชื่อว่า callbackfunction อยู่ก่อนแล้ว
function callbackfunction(e){
alert(e.name); //แสดง hello world (จะทำงานทันทีหลังจากโหลด JSONP เรียบร้อย)
}
เราก็สามารถดึงเอา argument ที่ได้ server ส่งมาให้ได้โดยง่าย
เมื่อเราเรียกคำสั่ง $.ajax และกำหนด dataType เป็น jsonp
jQuery จะเปลี่ยนจากการรีเควสท์ AJAX เป็นการแทรก tag script ดังกล่าวข้างต้นให้โดยอัตโนมัติ
ทำให้เราสามารถรีเควสข้อมูลแบบ GET ผ่านทาง script tag ได้ราวกับการรีเควส AJAX ตามปกติ
test.php
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=TIS-620" />
<title>JSONP</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(function(){
$("#jsonp-request").click(function(e){
$.ajax({
url:'http://goldxp.thport.com/jquery/jsonpdata.php',
type:'GET',
dataType:'jsonp', //ตรงนี้ทำให้สามารถ cross domain ได้
dataCharset:'jsonp',
success:function(e){
alert("jsonp data="+e[0].name);
}
});
e.preventDefault();
});
});
</script>
</head>
<body>
<a href="#" id="jsonp-request">JSONP-Request</a>
</body>
</html>
jsondata.php
<?php echo $_GET['callback']?>([{"name" : <?php echo rand(1,1000);?>}]);
เนื่องจากเป็นการเรียกข้ามโดเมนจึงมีเรื่องต้องระวังเรื่องความปลอดภัยเพิ่มขึ้นดังนี้ครับ
1) ฝั่ง server ถ้าจะรับข้อมูลจาก client เอาไปบันทึก แม้ว่าจะเชื่อถือ http referer ไม่ค่อยได้
แต่อย่างน้อยก็ควรจะตรวจสอบ http referer เพื่อกันการยิ่งข้อมูลมั่วๆ เข้ามา
2) ฝั่ง client ถ้าไม่ได้ตรวจสอบ json ให้ละเอียดว่าเป็นข้อมูลอย่างเดียวไม่มีคำสั่งปนเข้ามา
จะต้องรับข้อมูล json, jsonp หรือ javascript จาก server ที่น่าเชื่อถือเท่านั้น
เพราะอาจจะมีการแทรกคำสั่ง javascript เข้ามาใน json ได้เหมือนกันยกตัวอย่างเช่น
callbackfunction(function(){alert('test');}());
สำหรับ json ยังพอที่จะตรวจสอบข้อมูลได้ก่อนจะเรียกคำสั่ง eval(response_text)
แต่ jsonp ที่เรียกผ่านทาง tag script เป็นคำสั่งโดยตรงเลย
ดังนั้นควรจะรับข้อมูล jsonp ก็เฉพาะเว็บไซท์ที่น่าเชื่อถือเท่านั้นครับ