基本原理梳理、簡單Ajax應用。
原理
Ajax基本
- Ajax:異步JS與XML
- 同步、異步。
- XMLHttpRequest對象作為客戶端與服務器的中間媒介對象,實現Ajax。
HTTP相關知識
- HTTP是無狀態協議,不建立持久的信息,不在服務器保留信息。即,本次請求得到響應后,再次請求需要重新建立連接。
- HTTP請求和相應的基本流程:
1. 建立TCP連接
2. Web瀏覽器向Web服務器發送請求命令。
3. Web瀏覽器發送請求頭信息
4. 服務器應答
5. 服務器發送應答頭信息
6. 服務器向瀏覽器發送數據
7. 服務器關閉TCP連接
- HTTP請求基本流程:
1. 請求的方法或者動作:GET or POST
2. URL
3. 請求頭。客戶端的環境、身份信息等。
4. 請求體。待處理的信息。查詢字符串或者表單信息。
注:請求頭和請求體中間有空行,表示請求頭結束、請求體開始。
- HTTP響應基本流程
1. 狀態碼:用數字或者文字,表示請求成功與否。
1XX | 信息類。收到請求處理。 |
2XX | 成功。 |
3XX | 重定向。請求未成功。 |
4XX | 客戶端錯誤。如請求URL不存在:404 NOT FOUND |
5XX | 服務器錯誤。 |
2. 響應頭:對應請求頭。表示服務器信息。
3. 響應體:響應正文。
XMLHttpRequest(XHR)使用流程
- 基本按照HTTP請求、響應流程進行實現。當然側重點在客戶端這邊。
- XHR實例化。注意能力檢測:在IE6之前的版本(new ActiveXObject(version))、IE新版和一般瀏覽器(new XMLHttpRequest())之間考慮。
- XHR發送請求
1. open(method, url, async):請求方法、url、異步與否。
2. setRequestHeader():自定義頭部信息,可選。按照HTTP請求流程,在open和send方法間。
3. send(string):一般GET方法將信息附加到url后,所以這里string為null;而POST通常需要string。
- XHR取得響應
1. readystatechange事件的監聽一般放在open()方法之前。
2. 同步請求一般監聽:responseText,responseXML,status/statusText(對應上面提到的狀態碼)、getResponseHeader()/getAllResponseHeader()
3. 異步請求除了監聽上述的屬性或者方法之外,還應該結合readystatechange事件,考慮readyState屬性。
0 | 請求初始化、open未調用 |
1 | TCP連接建立、open已經調用 |
2 | 請求已經接收、受到頭信息 |
3 | 處理中、收到主體 |
4 | 請求已完成、響應就緒、響應完成。 |
- 確保請求、響應順利后,可以對數據進行處理。
簡單應用
描述
- 進行兩個HTTP請求
- 查詢員工信息,通過輸入員工的編號進行查詢。服務器進行相應處理(如果輸入為空、如果輸入編號不存在、如果輸入編號存在,返回相應的信息--responseText)
- 創建員工信息,輸入員工姓名、編號、性別、職位等等。服務器進行相應處理(如果沒有輸入完全、創建成功,返回相應信息)
服務器端(PHP)
- 簡單的語法和邏輯構造
- 本地部署一個Web服務器環境:用APPServ,具體用法參考文末鏈接。
- 對PHP進行測試:利用Fiddler,監聽HTTP請求,模擬客戶端提交進行請求。
頁面顯示(簡單的HTTP、CSS)
- 構造表單,創建兩個按鈕:查詢按鈕、提交按鈕。
Ajax與JS
- JS實現Ajax。
- 兩個按鈕分別綁定onclick事件,對應GET和POST請求。
- 在事件中進行上面提到的Ajax的基本流程,提交(插入)創建的POST請求代碼示意如下(暫定),其他具體代碼見文末GitHub鏈接。
- TIPS:在瀏覽器中F12打開控制台。選擇Network可以追蹤HTTP請求的一些信息,如請求頭、響應頭等等。
save.onclick = function(){ var createResult = document.getElementById("createResult"); var data = "name="+document.getElementById("staffName").value +"&number="+document.getElementById("staffNumber").value +"&sex="+document.getElementById("staffSex").value +"&job="+document.getElementById("staffJob").value; var request = createXHR(); request.onreadystatechange = function(){ if(request.readyState === 4){ if(request.status === 200){ createResult.innerHTML = request.responseText; }else{ alert("發生錯誤"+request.status); } } }; request.open("POST","server.php",false); request.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); request.send(data); }
相關知識
JSON
- 用於組織信息的語法,獨立與語言之外。與XML相比,快、短,且JS有簡單的解析和序列化方式,並可以比較方便的讀取和編輯。
- 語法簡單,采用名/值對的方式,具體語法參見《JS高程》Chapter 20章 JSON部分或者查閱文檔。
- JS中,解析JSON.parse()或者eval(),后者不安全;序列化JSON.stringfy()。
- jsonlint.com:JSON在線校驗工具。
- 應用在Ajax中,需要的更改:
1. 服務端:Content-type:application/json;將返回值調整成JSON的格式,設置必要的標志(如success:true/false)以供客戶端進行邏輯處理。
2. 客戶端:url指向新的PHP文件;對得到的響應數據進行解析:JSON.parse(responseText);訪問解析的對應字段,進行相關處理。
JQuery
- 詳情參見《鋒利的jQuery》Chapter 6,或者查閱文檔。
- jQuery本身支持Ajax和JSON:
- 記得引入JQ庫,可以引入在線地址。
-
$.ajax({ type:"POST", url:"serverJSON.php", dataType:"json", data:{ name:$("#staffName").val(), number:$("#staffNumber").val(), sex:$("#staffSex").val(), job:$("#staffJob").val() }, success:function(data){ if(data.success){ $("#createResult").html(data.msg); }else{ $("#createResult").html("出現錯誤:"+data.msg); } }, error: function(jqXHR){ alert("發生錯誤:"+jqXHR.status); } });
跨域
- 代理:在一個公共服務器上調用另一個域的資源。
- JSONP:常用於處理GET,語法簡單,JQuery支持。可以理解成一個中間媒介,在服務器和客戶端見做一個公共的約定處理:
1. 前端:dataType從“json”改為“jsonp”;添加屬性jsonp:callback
2. 后端:$jsonp=$_GET["callback"];修改返回值為$jsonp.("返回的數據")
3. 注意到“callback”就是雙方約定的處理,需要保持一致。然后需要返回的數據前需要於這個約定的名稱拼接。
- XHR2(HTML5)
比較新的處理方式,在舊版本瀏覽器中支持較差。只需要在服務端添加代碼:
//表示所有域名都可以訪問此資源 header("Access-Control-Allow-Origin:*"); //表示支持的方法 header("Access-Control-Allow-Methods:POST,GET");
鏈接
- 參考:《JS高程》Chapter 21
- GitHub:Ajax Demo
- Appserv: Appserv的使用 - 背包出發- 博客園