Displaying articles with tag ajax

Comet

Posted by PunNeng, Mon Jan 22 17:45:00 UTC 2007

AMp เขียนครับ

...เห็นมีคนพูดถึง comet แล้วพอดีวันนี้ว่าง ก็เลยไปดูๆ ซะหน่อย สรุปสั้นๆ ก็คือ comet มันก็ streaming ajax นั่นแหละ ดูท่าทางมันจะต้องการ software support ทาง server ด้วยเหมือนกัน เพราะว่า push technology มันทำงานทางฝั่ง server และตอนนี้ software ทาง server ก็เห็นจะมีแค่ lightstreamer นี่แหละ(มั้ง) ในหน้าเว็บมันนี่มีตัวอย่างเดียว แสดงราคาหุ้นแบบ realtime แต่เท่าที่ลองจับ packet มันดู ก็ยังเห็นว่ามันใช้ ajax polling ไปที่ server เป็นระยะเหมือนเดิม ทั้งๆ ที่ตาม concept แล้ว connection จะเกิดขึ้นเพียงครั้งแรกเท่านั้น แล้วก็เปิด connection ค้างไว้อย่างนั้นตลอดเลย ก็เลยไม่แน่ใจว่ามันอะไรกันแน่

ด้วยความสงสัยก็เลยลองเขียนตามบทความนี้ซะ ปรากฏว่า เมื่อเปิดด้วยบราวเซอร์ที่ไฟล์สคริปต์นี้โดยตรง ภาพที่เห็น คือข้อมูล(ภาพ)สุดท้ายที่ปรากฏ .... ซะงั้น

ไม่แน่นะ มันอาจจะใช้กับ ajax ก็ได้ ก็เลยลองเขียนด้วย ajax ดูแล้วก็ให้มัน response ออกมาเป็น text แทน พอทดสอบ ผลปรากฏว่า ข้อมูลมาพรวดเดียวหมดเลย ไม่ได้มาแบบ streaming - -''

จากการทดลองทั้งสองอันนี้ ทำให้...งง...งงโคตรๆ ว่า มันเป็น persistance connection ยังไงวะ เท่าที่ลองคิดดู รันแบบนี้ ต้องติด time limit ของ php แน่ๆ แล้วก็อาจจะติด time out ของ browser หรือ network ด้วย แล้วเทคโนโลยีนี้มันจะสำเร็จได้ไงเนี่ย - -*

อ่านเจอมาว่า rss feed ก็เป็น push technology เหมือนกัน แต่มันบอกว่า ในทางเทคนิคแล้ว มันใช้ polling นั่นแหละ ..เวรกรรม สรุปว่ายังไงวะเนี่ย โคตรงง

เอาเหอะ ตอนนี้ยังโง่อยู่ ยังมองอะไรๆ ใน comet นี้ไม่ค่อยออกว่ามันคิดอะไรอยู่ถึงเป็น comet ขึ้นมา แต่ที่แน่ๆ comet คงเหมือนงาน streaming ทั่วๆ ไปที่ไม่ได้ใช้กันเกร่อนัก อย่างน้อยไอ้พวก shared host ก็ไม่ได้ใช้แน่ๆ เพราะ server มันต้องเปิด thread ตาม connection ที่เข้ามา ทำให้ต้องใช้ software เพื่อการนี้โดยเฉพาะ (ต่อไปอาจจะมี mod สำหรับ apache ก็ได้)

0 comments | Filed Under: General | Tags: ajax

Attacking Ajax Application

Posted by PunNeng, Thu Dec 07 09:47:00 UTC 2006

Amp เขียนครับ

เมื่อวานไปเจอ presentation ที่เกี่ยวกับการโจมตี Ajax application ดูแล้ว หลักๆ เหมือนจะเป็นการโจมตีที่จุดอ่อนระหว่างการรับส่งข้อมูล client กับ server ซะมากกว่า เพราะปกติเวลาเราเขียน ajax app เนี่ย จะเผลอมองกันว่า ajax กับ cgi นั้น มันเป็น app ตัวเดียวกัน ฉะนั้น จึงไว้วางใจข้อมูลที่ส่งมาจาก ajax มากไปหน่อย ซึ่งจริงๆ แล้ว ไม่ว่าจะเป็น request ที่เกิดจาก ajax หรือ client เอง cgi ก็ไม่สามารถแยกแยะได้อยู่แล้ว ว่าเป็น request จากอะไร ดังนั้น policy การจัดการกับข้อมูลที่มาจาก ajax ควรจะอยู่ในระดับเดียวกับการจัดการข้อมูลที่มาจาก client อย่างพวก การป้องกัน injection ทั้งหลาย (sql injection, js injection, html injection ... ) นี่ขาดไม่ได้เลย

ใครสนใจ เชิญดาวน์โหลดไปอ่านได้เลยครับ http://www.isecpartners.com/files/iSEC-AttackingAJAXApplications.BH2006.pdf

แก้ไขล่าสุด วันที่ 18 กรกฏาคม 2550 เวลา 23.52 น.

0 comments | Filed Under: General | Tags: ajax

AJAX on Rails(2)

Posted by PunNeng, Sat Mar 04 22:27:00 UTC 2006

ต่อจากคราวที่แล้ว มาต่อกันด้วยการใช้ form_remote_tag จะมีลักษณะเหมือนกันกับ link_to_remote แต่คราวนี้มันจะไปทำงานร่วมกับ form แทน มาดูตัวอย่างกันดีกว่า

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
<html>
  <head>
    <title>Ajax List Demo</title>
    <%= javascript_include_tag "prototype" %>
  </head>
  <body>
    <h3>Add to list using Ajax</h3>
    <%= form_remote_tag(:update => "my_list",
                       :url => { :action => :add_item },
                       :position => "top" ) %>
      New item text:
      <%= text_field_tag :newitem %>
      <%= submit_tag "Add item with Ajax" %>
    <%= end_form_tag %>
    <ul id="my_list">
      <li>Original item... please add more!</li>
    </ul>
  </body>
</html>

มันจะเหมือนกับการประกาศ <form>.....</form> แต่ปุ่ม submit แทนที่พอจิ้มแล้ว มันจะต้องสั่งไปที่ file อันนึง แล้วมันจะ redirect ไปหน้านั้น แต่อันนี้มันจะยิงไปที่ method ที่เราสั่งแทน มันก็ไม่เกิดการ refresh ขึ้น โดย parameter ที่ส่งไปไนั้น จะมี id ของ tag ที่เราจะทำการ update อันถัดไปจะเป็น url ก็คือ method ที่เราจะสั่งให้มันทำงาน และอีกตัวนึงที่จะมีก็ได้ หรือไม่มีก็ได้ คือ ตำแหน่ง จะได้หน้าตาแบบนี้มา แล้วมาดูที่ฝั่ง controller กันบ้าง

  1
  2
  3
  4
  5
  6
  7
  8
class ListdemoController < ApplicationController
  def index
  end

  def add_item
    render_text "<li>" + params[:newitem] + "</li>"
  end
end

add_item จะทำการคุม list เมื่อรับค่า newitem เข้ามาจาก form หน้าตาจะเป็นแบบนี้เมื่อทำเสร็จแล้ว

โย่

ส่วนสำคัญอีกอันนึงคือการใช้ตัวคอยตรวจจับอย่าง Observers ตัว Observers จะมีหน้าที่คอยตรวจจับการเปลี่ยนแปลงของ tag ที่เราต้องการจะตรวจจับ เมื่อมีการเปลี่ยนแปลงมันจะไปเรียกให้ method ใน controller ให้ทำงาน เช่น

  1
  2
  3
  4
  5
  6
  7
  8
<label for="searchtext">Live Search:</label>
<%= text_field_tag :searchtext %>
<%= observe_field(:searchtext,
                 :frequency => 0.25,
                 :update => :search_hits,
                 :url => { :action => :live_search }) %>
<p>Search Results:</p>
<div id="search_hits"></div>

ในนี้จะมี textfield มาตัวนึง ซึ่งมันจะถูกตรวจทุกๆ 0.25 วินาที เมื่อมีการเปลี่ยนแปลง ตัว live_search จะถูกเรียกให้ทำงาน ในกรณีที่ไม่ใส่ค่า :frequency มันจะสั่ง method ให้ทำงานในทุกๆ ครั้งที่มีการเปลี่ยนแปลง ดูตัวอย่างเท่ๆ ได้ที่ http://blog.curthibbs.us/ จะมี searchbox อยู่ ลองใช้ดูละกัน

website

เอาละ คงจะรู้จัก AJAX กันมากขึ้น จากที่ผมเคยว่าไปแล้ว และก็อันนี้ ของใหม่ ที่ทำบน Rails สำหรับคนที่ต้องการจะใช้ ควรจะพิจารณาในหลายๆ ด้านก่อน อย่าคิดว่าจะใช้เพียงเพราะว่าความเท่อย่างเดียว เพราะสิ่งที่มันไม่ค่อยดีกับ AJAX ก็มีเหมือนกัน กล่าวคือ เมื่อเราต้องการจะ bookmark มันไง ถ้าหากว่าเราทำนั่นๆๆ นี่ๆๆ ไปหมดแล้ว แล้วอยากจะเก็บ link มันเอาไว้ มันก็จะเก็บไว้นะ แต่พอที่เรามาที่ link นี้อีกที มันก็จะกลับสู่หน้าแรก แล้วที่ทำๆๆ มาล่ะ ? อีกอันคือปุ่ม back บนหน้า browser เพราะเมื่อเรารู้สึกว่า มันผิดแล้ว อยากจะ back กลับไปจังเลย ถ้าจิ้มละก็ มันก็จะไป link ที่เราเคยมา นั่นหมายความว่า เปลี่ยนหน้าไปเลย เพราะ url มันก็เป็นอันเดิม พอสั่ง back มันก็กลับไป url ก่อนหน้าที่เราเคยเข้ามา

หรือในกรณีที่เราอยากจะทำการสร้างใหม่ทั้งหน้า
เหนื่อยตายเลย แบบนี้ เราจะนิยมโหลดหน้ามันมาใหม่เลยดีกว่า เพราะจะได้ไม่ต้องมาสั่งลบ html dom แล้วสั่งสร้างหน้าของเราใหม่อีกที แต่ในกรณีนี้ เราอาจจะใช้ iframe เข้าช่วยได้

ก็คงจะแล้วแต่ทุกท่านละกัน ใช้งานอะไร ก็ให้มันเหมาะสมกับงานละกัน

ข้อมูลจาก http://www.onlamp.com

แก้ไขล่าสุด วันที่ 3 กรกฏาคม 2550 เวลา 21.58 น.

0 comments | Filed Under: Ruby on Rails | Tags: ajax

AJAX on Rails

Posted by PunNeng, Wed Mar 01 04:11:00 UTC 2006

ช่วงนี้ กระแส AJAX มาแรงมากครับ เข้าไปท่องเว็บบอร์ดที่ไหน ก็ต้องเจอ AJAX กันทุกเว็บบอร์ด แม้กระทั่งในนี้ก็ยังมี เหอๆ สำหรับท่านที่เพิ่งมาอ่านใหม่ ถ้ายังไม่เข้าใจว่า AJAX คืออะไร search เอานะครับ

อย่างที่บอกไปแล้ว ช่วงนี้ผมทำ Ruby on Rails อยู่ รู้สึกทึ่งกับความสามารถของ Rails มากมาย มันเป็น magic บนเว็บเลยนะ อะไรมันจะง่ายขนาดนี้

1 feature ที่ผมพบคือ AJAX on Rails นี่แหละ มันสร้างความมหัศจรรย์ ให้กับผมมาก จากตอนแรกที่เราต้องส่ง XML โยนกันไปโยนกันมาระหว่าง backend ไปยัง frontend แล้วพอรับ XML ชุดนั้นมาแล้ว เราจะต้องไปเขียนสั่ง html dom ให้ทำนั่น วาดนี่ ลบอันนั้น โอ้ย สาระพัด เปลืองพลังงานมากมายเลยครับ แต่ AJAX on Rails ช่วยให้พลังถดถอยน้อยมากมายยยย เราไม่ต้องไปสนใจ XML อะไรนั่นแล้ว หรือต้องมานั่งสั่ง html dom ให้ทำงานตามความต้องการ มันจะมี API สำหรับจัดการ html dom ทั้งหมด

มาดูหลักการคร่าวๆ ของ Rails ที่ไปจัดการกับ AJAX ดีก่า

Rails มันมี library ต่างๆ นานา ไว้จัดการกับ AJAX อยุ่แล้ว สบายมากๆ เพียงแค่เรียกใช้ method ที่จัดไว้ให้ ก็เรียบร้อยแล้ว มาดู process รวมๆ ก่อน เหมือนๆ กันทุกเว็บ

  1. user ทำอะไรบางอย่างบนหน้าเว็บ ก็คือ event ต่างๆ นั่นเอง เช่น กดปุ่ม กด link หรือเปลี่ยนแปลง data ใน textfield
  2. แล้วมันก็จะทำการส่งแบบ asynchronously ไปยัง server โดยผ่าน XMLHttpRequest
  3. แล้ว serverside ก็จะทำการอะไรสักอย่าง ที่เรากำหนดไว้ แล้วส่งกลับมายังหน้าเว็บของเราโดย XML
  4. แล้วตัว JavaScript (จะถูกสร้างโดย Rails อย่างอัติโนมัติ) ก็จะทำการ update หน้าเว็บโดยใช้ข้อมูลจาก XML ที่รับมานี่แหละ

แต่ที่เราจะมาดูคือ มาดูว่า Rails มันมีการจัดการหน้าเว็บของเราที่มันแสนง่าย ยังไง

link_to_remote

อย่างที่บอกไป Rails มันจะมีพวก library ที่บรรจุ method ต่างๆ ที่ไว้จัดการกับหน้าเว็บ ซึ่งหนึ่งในนั้นก็คือ link_to_remote มาค่อยๆ พิจารณาหน้า page ง่ายๆ ก่อนดีกว่า คือหน้านี้จะมี link สำหรับแสดงเวลา ใน app ก็จะทำการใช้ AJAX ทาง link_to_remote นี่แหละ ในการที่จะรับค่าเวลากลับมา index.rhtml

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
<html>
  <head>
    <title>Ajax Demo</title>
    <strong><%= javascript_include_tag "prototype" %></strong>
  </head>
  <body>
    <h1>What time is it?</h1>
    <div id="time_div">
      I don't have the time, but
      <strong><%= link_to_remote( "click here",
                         :update => "time_div",
                         :url =>{ :action => :say_when }) %></strong>
      and I will look it up.
    </div>
  </body>
</html>

อันนี้จะมีสอง method ก็คือ javascriptincludetag() มันจะนำ Prototype ซึ่งเป็น framework อีกตัวหนึ่งของ JavaScript เข้ามาให้ Rails ทำการเรียกใช้ ตัวถัดมาก็คือ link_to_remote() ในการเรียกใช้ form ก็จะมี 3 parameter คือ

  1. text ที่จะแสดงบนปุ่ม
  2. id ของ html dom ที่จะทำการ update
  3. ตัว action ซึ่งมันจะไปเรียก method ที่เราเขียนไว้ใน Controller

ก่อนคลิก แล้วมาดูที่ตัว Controller กันต่อ (หลายๆ คนอาจจะงง แต่ไม่นานหรอกคับ เดี๋ยวจะว่าเกี่ยวกับ Ruby on Rails ต่ออีก)

  1
  2
  3
  4
  5
  6
  7
  8
class DemoController < ApplicationController
  def index
  end

  def say_when
    render_text "<p>The time is <b>" + DateTime.now.to_s + "</b></p>"
  end
end

ผลที่ได้หลังจากคลิก หน้า index นี้ ก็ไม่มีอะไรมาก ก็จะมี link ให้คลิกเพื่อแสดงเวลา ตัว say_when method ก็จะทำการ render ให้ใหม่ จริงๆแล้ว process เดิมๆ ของ AJAX ก็ยังคงอยู่ ไม่ว่าจะเป็น XMLHttpRequest หรือตอนส่งค่ากลับมาเป็น XML แต่ตัว Rails นี่แหละ ทำให้เราไม่ต้องไปเสียเวลาจัดการกับส่วนนี้ สบายที่สุด

ยังมี optional parameter อยู่อีกตัวนึง

  1
  2
  3
  4
<%= link_to_remote( "click here",
                   :update => "time_div",
                   :url => { :action => :say_when },
                   :position => "after" ) %>

ตัวที่เพิ่มเข้ามาคือ position ก็จะมีค่าที่เป็นไปได้คือ before, after, top, และ bottom before กะ after จะทำนอก tag ที่เราระบุ id แต่ top กะ buttom จะทำใน tag ที่เราระบุ id เช่นกัน ผลลัพธ์

ยาวจัง ยังไม่จบครับ คราวหน้ามีต่อ

ข้อมูลจาก http://www.onlamp.com

แก้ไขล่าสุด วันที่ 3 กรกฏาคม 2550 เวลา 21.58 น.

0 comments | Filed Under: Ruby on Rails | Tags: ajax

Ajax(2)

Posted by PunNeng, Tue Jan 03 23:42:00 UTC 2006

กลับมาจากบ้านแล้ววว พักผ่อนกันเต็มที่

มาทำความเข้าใจในใส่ code สำคัญๆ ของ AJAX ดีกว่า เริ่มจาก

if (window.XMLHttpRequest) { // Mozilla, Safari,...
    xmlhttp = new XMLHttpRequest();
    if (xmlhttp.overrideMimeType) {
        xmlhttp.overrideMimeType('text/xml');
    }
} else if (window.ActiveXObject) { // IE
    try {
        xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
    } catch (e) {
        try {
            xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
        } catch (e) {}
    }
}

code ชุดนี้ เป็นตัวสร้าง HTTPRequest ไม่่ต้องไปคิดอะไรมากสำหรับ code ชุดนี้ เอาไปแปะได้เลย

xmlhttp.onreadystatechange = function(){
    // do the thing
};

code ชุดนี้ จะทำการ ทำบางอย่าง เมื่อเราโหลดข้อมูลจาก XMLHttpRequest เสร็จแล้ว

xmlhttp.open('GET', 'http://www.example.org/some.file', true);
http_request.send(null);

ตรงส่วนนี้ จะทำการส่งข้อมูล ไปยัง Link ที่เราต้องการส่งไป paremeter ตัวแรก จะเป็นตัวกำหนัด request method - get post หรือ head paremeter ตัวที่สอง คือ link ที่เราจะส่งไป parameter ตัวที่สาม เป็นตัวบอกว่าจะให้ทำการ execute JavaScript ในขณะที่ยังไม่มีการส่ง response กลับมา ถ้าต้องการส่งโดย POST ให้เพิ่่มไปว่า

xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

โดย function send ต้องส่ง parameter ไปด้วย เช่น

xmlhttp.send('myVar=myValue');

ต่อไป

if (xmlhttp.readyState == 4) {
    // everything is good, the response is received
} else {
    // still not ready
}

โดย readyStage แต่ละตัวคือ 0 (uninitialized) 1 (loading) 2 (loaded) 3 (interactive) 4 (complete)

if (http_request.status == 200) {
    // perfect!
} else {
    // there was a problem with the request,
    // for example the response may be a 404 (Not Found)
    // or 500 (Internal Server Error) response codes
}

code ชุดนี้เป็นตัว check status ถ้าเป็น 200 ถือว่า ok แต่ถ้าไม่ใช่ ตัวเลขอื่นก็จะมีความหมายต่างออกไป โดยสามารถดูได้จาก W3C site

หลังจากเสร็จสิ้นแล้ว property ที่จะทำการส่งข้อมูลที่จะใช้กลับมาคือ

xmlhttp.responseXML - สำหรับ XML 
xmlhttp.responseText - สำหรับ text

ตัวอย่างง่ายๆ

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
<script type='text/javascript' language='javascript'>;
var http_request = false;
function makeRequest(url) {
    http_request = false;
    if (window.XMLHttpRequest) { // Mozilla, Safari,...
        http_request = new XMLHttpRequest();
        if (http_request.overrideMimeType) {
            http_request.overrideMimeType('text/xml');
            // See note below about this line
        }
    } else if (window.ActiveXObject) { // IE
        try {
          http_request = new ActiveXObject('Msxml2.XMLHTTP');
        } catch (e) {
         try {
          http_request=new ActiveXObject('Microsoft.XMLHTTP');
         } catch (e) {}
        }
    }

    if (!http_request) {
       alert('Giving up : Cannot create an XMLHTTP instance');
        return false;
    }
    http_request.onreadystatechange = alertContents;
    http_request.open('GET', url, true);
    http_request.send(null);
}

function alertContents() {
    if (http_request.readyState == 4) {
        if (http_request.status == 200) {
            alert(http_request.responseText);
        } else {
            alert('There was a problem with the request.');
        }
    }
}
</script>;
<span style='cursor: pointer; text-decoration: underline'
    onclick="makeRequest('test.html')">
        Make a request
</span>

ชุดนี้แทรกลงไปใน head tag ถ้าเราทำการ click ที่ Make a request มันจะทำการเรียก makeRequest() โดยส่ง URL ไปตัวนึง คือจุดหมายที่เราต้องการจะโหลดข้อมูล หลังจากที่ได้รับข้อมูลเสร็จสิ้น onreadystatechange ก็จะทำงานโดยไปเรียก alertContents() ถ้ามันโหลดข้อมูลมาเสร็จ ก็จะทำการ alert response text ออกมา

โดยตัว test.html ให้ใส่ code ไปว่า

up to you

ทดลองได้ที่นี่

ถ้าเป็น XML เราจะเปลี่ยนนิดหน่อย โดยสร้างตัว test.xml ยึ้นมา โดยข้างในใส่ว่า

  1
  2
  3
  4
<?xml version='1.0' >
<root>
    I am a test.
</root>

แล้วก้อเปลี่ยน URL ของเราหน่อย โดยเปลี่ยนจาก test.html เป็น test.xml แทน

จากนั้นเปลี่ยนตรง responseText ใ้ห้เป็น

  1
  2
  3
var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);

ทดลองได้ที่นี่

ข้อมูลจาก http://developer.mozilla.org/en/docs/AJAX:Getting_Started

แก้ไขล่าสุด วันที่ 29 มิถุนายน 2550 เวลา 1.31 น.

0 comments | Filed Under: General | Tags: ajax

codegent: we're hiring