1. 同步與非同步
    1. 同步HTTP請求
      1. 請求-->顯示-->互動-->暫停-->請求-->顯示-->互動-->暫停 …
      2. 需要不斷重新刷新整個頁面
        1. 會出現一段時間的空白
    2. 非同步HTTP請求
      1. 請求-->顯示-->互動-->(請求)互動-->(請求)互動…
      2. 非同步HTTP請求在顯示、執行互動不需要再暫停操作,可以馬上執行所需的互動
      3. 只向伺服器要求一小部份資料,然後更新頁面的一小部份, 不需要重新刷新整個頁面,也不會出現一段時間的空白
    3. 非同步好處
      1. 減輕伺服器的負擔,加快瀏覽速度
        1. 只給所需
      2. 帶來更好的用戶體驗
        1. 更流暢的畫面
      3. 標準化技術,主流瀏覽器都支援
      4. 促進頁面呈現與資料分離
        1. 提高可維護性
  2. ajax組成
    1. ajax不是單一技術,是集4種技術而成,JavaScript、CSS、DOM、XMLHttpRequest。 (或說5種,再加上(X)HTML)
    2. ajax技術組成
      1. JavaScript
        1. 通用指令碼語言。是撰寫ajax主要程式語言
      2. CSS
        1. 為Web頁面元素提供視覺化樣式的定義方法, ajax透過修改CSS樣式,改變使用者介面
      3. DOM
        1. ajax可以在執行時透過DOM來改變使用者介面,或局部更新某個節點
      4. XMLHttpRequest
        1. XMLHttpRequest物件允許Web開發人員向伺服器以非同步方式取資料, 資料格式通常是XML或是文字,目前較流行為JSON
          1. JSON
  3. XMLHttpRequest物件
    1. 能夠直接在Client使用Javascript來提出HTTP請求
    2. IE內建MSXML剖析器有多個版本,其提供的XMLHttpReqest物物也有多個版本
      1. XMLHttpRequest版本
        1. 2.0(IE5)
          1. msxml.dll
          2. Microsoft.XMLHttp
        2. 2.6
          1. msxml2.dll
          2. MSXML2.XMLHttp
        3. 3.0(IE6)
          1. msxml3.dll
          2. MSXML2.XMLHttp.3.0
        4. 4.0
          1. msxml4.dll
          2. MSXML2.XMLHttp.4.0
        5. 5.0
          1. msxml5.dll
          2. MSXML2.XMLHttp.5.0
        6. 6.0
          1. msxml6.dll
          2. MSXML2.XMLHttp.6.0
    3. 建立XMLHttpRequest物件
      1. 在Mozilla和Safaris是內建物件
        1. var xmlHttp=new XMLHttpRequest();
      2. 在IE6之前是透過ActiveX控制項物件(由MSXML提供)
        1. var xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
      3. IE7之後,同時支援原生XMLHttpRequest物件(預設值)和ActiveX控制項物件
      4. var xmlHttp; function createXMLHttpRequest(){ if (window.XMLHttpRequest) //支援原生型 xmlHttp = new XMLHttpRequest(); else if (window.ActiveXObject) //IE6以下 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); }
  4. 屬性/方法
    1. 屬性
      1. XMLHttpRequest屬性
        1. readyState
          1. 回傳狀態值
          2. 0
          3. uninitalized,未初始化
          4. 1
          5. loading,載入中
          6. 2
          7. loaded,載入完成
          8. 3
          9. interactive,可互動
          10. 4
          11. completed,完成
          12. 唯讀屬性,目前狀態
        2. responseBody
          1. 唯讀屬性,取得伺服器的回應,傳回非符號位元組的陣列
        3. responseSteam
          1. 唯讀屬性,取得伺服器的回應,傳回IStream資料流物件
        4. responseText
          1. 唯讀屬性,取得伺服器的回應,傳回字串
        5. responseXML
          1. 唯讀屬性,取得伺服器的回應,傳回XML DOM物件,可作DOM處理
        6. status
          1. 唯讀屬性,取得HTTP狀態碼
          2. 回傳狀態碼
          3. 200
          4. OK,請求成功
          5. 202
          6. 請求被接收,但處理未完成
          7. 400
          8. 錯誤的請求
          9. 404
          10. Not Found,找不到網頁
          11. 500
          12. Internal Server Error,內部錯誤
          13. …其他網頁錯誤碼
        7. statusText
          1. 唯讀屬性,取得HTTP狀態訊息字串
        8. onreadystatechange
          1. 存取屬性,執行readyState屬性改變的事件處理,設定處理的程序
    2. 方法
      1. XMLHttpRequest方法
        1. abort()
          1. 取消目前HTTP請求
        2. getAllResponseHeaders()
          1. 取得全部HTTP標頭內容
        3. getResponseHeader("指定Header名稱")
          1. 取得指定HTTP標頭名稱的內容
        4. open("GET|POST","URL",async,userid,pwd)
          1. 開啟HTTP請求
          2. GET
          3. 取得伺服器回應
          4. POST
          5. 傳送資料到伺服器
          6. URL
          7. 請求的XML文件或伺服端程式(ASP.NET, PHP, JSP...)
          8. async
          9. 布林值, 預設true,false表示需要等到伺服器回應後才繼續執行Javascript
          10. userid, pwd
          11. 伺服器需要id/password,才需要使用
        5. send("參數")
          1. 傳送HTTP請求到伺服器
          2. 參數表示要向伺服器發送的資料
          3. 格式為查詢字串的形式
          4. var param = "name=Bruce&age=18";
          5. 在open中指定為GET,則參數作為查詢字串傳送, 如果指定為POST,則作為HTTP的POST方法傳送, 對於send()方法而言,此參數為必需, 如不發送任何資料,請傳送null即可。
          6. GET
          7. xmlHttp.send(null);
          8. POST
          9. xmlHttp.send(param);
        6. setRequestHeader("自訂Header名稱",value)
          1. 自訂HTTP標頭資料
          2. 如果使用POST方法,在發送之前必須設定HTTP標頭
          3. xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
          4. xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
    3. GET/POST
      1. function startRequest(){ createXMLHttpRequest(); //建立xmlHttp物件 xmlHttp.open("GET","Demo.aspx"); xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState == 4 && xmlHttp.status == 200) alert("服務器傳回訊息: " + xmlHttp.responseText); } xmlHttp.send(null); }
        1. 參數
          1. IE會自動暫存非同步的結果,解決方法是每次非同步請求的URL不同, 我們可以加上一個伺服器不需要的參數,讓每次的URL都不同
          2. var url = "Demo.aspx?timestamp=" & new Date().getTime(); xmlHttp.open("GET",url, true);
          3. GET請求如果有參數,直接放入URL網址中
          4. var queryString = "name=Bruce&age=18"; var url = "Demo.aspx?" + queryString + "&timestamp=" + new Date().getTime();
          5. POST請求有參數,統一放在send()中來傳送
          6. var queryString = "name=Bruce&age=18"; var url = "Demo.aspx?timestamp=" & new Date().getTime(); xmlHttp.open("POST",url,true); ... xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); xmlHttp.send(queryString);
          7. POST方法中文會出現亂碼
          8. 在IE8與MF3上測試無此問題,但為了相容性還是建議加上解決方法
          9. 這是因為XMLHttpRequest物件在處理傳回responseText/XML時是使用UTF-8編碼, 建議使用解決方法2,對回傳的資料進行decodeURIComponent()解碼即可
          10. 解決方法
          11. 1
          12. 對要傳送的資料進行兩次encodeURI()編碼, 以解決中文亂碼問題
          13. ... xmlHttp.send(encodeURI(encodeURI(queryString)));
          14. 對傳回資料responseText/XML再進行一次decodeURI()解碼
          15. ... responseDiv.innerHTML = decodeURI(xmlHttp.responseText);
          16. 2
          17. setRequestHeader直接宣告(charset)使用UTF-8
          18. xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); xmlHttp.send(queryString);
          19. 對傳回資料responseText/XML進行decodeURIComponent()解碼
          20. ... responseDiv.innerHTML = decodeURIComponent()(xmlHttp.responseXML);
    4. onreadystatechange
      1. ajax的重點在狀態改變後的事件處理函式(handler), 也可以說,這是唯一我們必須自訂(手動)設計程式碼 的地方,換個方向說,我們在請求/回應,而伺服器 回應資料後,我們要如何處理及顯示到網頁上(DOM)
      2. 同時觸發非同步問題
        1. 如果我們必須同時觸發(呼叫)多個ajax物件, 因為我們通常都是把建立的ajax物件的xmlHttp宣告為全域變數, 所以可能會產生覆蓋的情況
        2. 解決
          1. 就是將xmlHttp宣告為區域變數來處理, 並在收到伺服器資料且處理完後,手動刪除
          2. function getData(){ var xmlHttp=""; createXMLHttpRequest(); xmlHttp.onreadystatechange = function(){ ... delete xmlHttp; xmlHttp = null; } }
          3. delete關鍵字
          4. 刪除物件的property
          5. The delete operator deletes an object, an object's property, or an element at a specified index in an array.