วันพฤหัสบดีที่ 17 กุมภาพันธ์ พ.ศ. 2554

jquery Stop Propagation

ลำดับการเกิด event จาก element หนึ่งๆ จะเริ่มต้นจาก elment ด้านใน หรือด้านนอก ในแต่ละ browser จะต่างกัน
แต่ jquery จะกำหนดให้ลำดับการเกิดแบบ Event bubbling นั่นคือเริ่มจากด้านในก่อน
(โดยทั่วไปนะแต่อาจมีเทคนิคพิเศษที่ทำให้ลำดับการเกิด event เปลี่ยน)
http://www.quirksmode.org/js/events_order.html
http://api.jquery.com/bind/



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.js"></script>
<script type="text/javascript">
//<![CDATA[
$(function(){
$('#xxx').click(function(event){
alert('div event');
});
$('#xxx button').click(function(event){
alert('button event');
if (confirm('stop next event?'))
return false;
});
});
//]]>
</script>
</head>
<body>

<div id="xxx">
###<button>button in div</button>###
</div>

</body>
</html>


selector จะใช้สำหรับการเลือก element ครับ
แต่ถ้าจะจัดการกับ event ที่มี element ที่คาบเกี่ยวกัน (ซ้อนทับกัน)
แค่ selector ยังไม่พอครับ เพราะ event handler
ของตัวที่คลุมอยู่ก็กระทบกับตัวที่อยู่ข้างในมันด้วย จึงต้องใช้คำสั่ง stop propagation ควบคุมอีกทีหนึ่ง

การใช้คำสั่ง return false; ข้างบนี้จะเทียบได้กับ preventDefault(); และ stopPropagation(); พร้อมๆ กันครับ

stopPropagation()
preventDefault()

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