วันอังคารที่ 1 กุมภาพันธ์ พ.ศ. 2554

jQuery ช่วยส่งข้อมูลแบบ Cross Domain ง่ายนิดเดียว

การส่งค่า 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 ก็เฉพาะเว็บไซท์ที่น่าเชื่อถือเท่านั้นครับ

2 ความคิดเห็น:

  1. ทำไมผมรันแล้วมันไม่ขึ้นอะไรเลยเหรอครับ
    ผมลองใช้ทั้งในตัวอย่าง (http://goldxp.thport.com/jquery/jsonpdata.php) และที่ผมสร้างขึ้นมาเอง มันก็ไม่ขึ้นอะไรเลยอะครับ ลองหลาย browser แล้วเหมือนกัน
    ไม่ทราบว่าต้องไปทำอะไรก่อนหรือเปล่าครับ

    ตอบลบ
  2. โค้ดเก่าจะใช้ไฟล์ jquery.js ต้องหาไฟล์ jquery.js นี้มาไว้ที่เดียวกับไฟล์ php ก่อนครับ
    <script type="text/javascript" src="jquery.js"></script>

    แต่ถ้าตามโค้ดใหม่จะไม่ต้องดาวน์โหลดไฟล์มาไว้ที่เดียวกันก็ได้ครับ
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>

    และให้วางไฟล์โปรแกรมไว้ใน http://localhost ครับ ถ้าไว้ข้างนอก browser มักจะเตือนเกี่ยวกับ security ครับ

    ตอบลบ