Ajax與伺服器(JSON)通訊
Ajax這個詞,不代表任何東西,它只是稱呼一系列促進客戶端與伺服器通訊的技術時所用的一個術語。伺服器通訊時Ajax技術的核心內容,其目標就是從客戶端向伺服器發送訊息,並接受後者的回傳,以求在此過程中創造出更好地打用戶體驗來。 Ajax之前所有的伺服器通訊都是在伺服器上完成的,所以那是若想重繪頁面的一部分,要麼使用iframe(已淘汰),要麼刷新整個頁面。這兩種方式都稱不上是良好的使用者體驗。
Ajax提供了兩類伺服器通訊手段:同步通訊和非同步通訊。
非同步通訊Ajax比同步通訊要常見的多了,大概是98%的使用頻次。非同步意味著此類Ajax呼叫並不和其他任務同時觸發,這種通訊行為發生在後台,具備相當的獨立性,與頁面和web應用程式相互分離。
使用非同步調用,可以避免同步調用的阻塞性,它不需要與頁面中的其他HTTP請求擠在一起處理。
XMLHttpRequest物件
XMLHttpRequest物件是所有Ajax呼叫的核心。我們的目的是使用Ajax技術非同步獲取JSON中的數據,並以適當的形式將其展現出來:
//创建ajax通信服务器对象 function getHTTPObject(){ "use strict"; //注意使用严格模式 var xhr; //使用主流的XMLHttpRequest通信服务器对象 if(window.XMLHttpRequest){ xhr = new window.XMLHttpRequest(); //如果是老版本ie,则只支持Active对象 } else if(window.ActiveXObject){ xhr = new window.ActiveXObject("Msxml2.XMLHTTP"); } //将通信服务器对象返回 return xhr; }
跨瀏覽器的兼容問題:微軟Ie發明了XMLHttp對象,那就導致了IE5、IE6只支援ActiveXObject對象,所以要考慮對它的相容問題。
創建Ajax呼叫
首先,我在本地的data目錄下創建好了Salad.json文件,等待Ajax程式去調用它:
//ajax JSON Salad var ingredient = { "fruit":[ { "name" : "apple", "color" : "green" }, { "name" : "tomato", "color" : "red" }, { "name" : "peach", "color" : "pink" }, { "name" : "pitaya", "color" : "white" }, { "name" : "lettuce", "color" : "green" } ] };
然後要做的是傳向伺服器發送和接受請求和接受回的資料:
在接收到傳回的伺服器通訊物件「xhr」後,我們緊接著要做的是使用readystatechange 事件對通訊物件「xhr」進行Ajax請求狀態和伺服器狀態,當readystate狀態要求完成和status狀態伺服器正常時在進行之後的通訊工作。
//输出ajax调用所返回的json数据 var request = getHTTPObject(); request.onreadystatechange = function(){ "use strict"; //当readyState全等于“4”状态,status全等于“200”状态 代表服务器状态服务及客户端请求正常,得以返回 if(request.readyState ===4 || request.status ===200 ){ //为了方便起见,将数据打印到浏览器控制台(F12查看) console.log(request.responseText); } //使用GET方式请求.json数据文件,并且不向服务器发送任何信息 request.open("GET","data/ingredient.json",true); request.send(null); };
Ajax也透過GET和POST方法進行調用,GET方式會把資料暴露在URL之中,所以它的處理工作較少;POST相對較安全,但性能不如GET。 接下來分別使用 open()和 send()方法對伺服器請求資料檔案和傳送資料。
通常在實際的開發專案中,不可能僅僅有一個Ajax呼叫。為了重複使用,為了方便起見,我們需要將這個Ajax程式封裝成複用函數,在這裡我傳入了一個outputElement參數,用於給用戶提示等待;還傳入了一個callback參數,用於傳入一個回呼函數,根據使用者在搜尋框鍵入的關鍵字在JSON檔案中進行匹配,將適當的資料渲染到頁面回應的位置:
//将其封装成一个供调用函数 function ajaxCall(dataUrl,outputElement,callback){ "use strict"; //这是一段截取的js(ajax)代码 var request = getHTTPObject(); //我想要提醒大家的是:当网页的某个区域在向服务器发送http请求的过程中,要有一个标识提醒用户正在加载... outputElement.innerHTML = "Loding..."; //也可以根据各位的需求添加一个循环小动画 request.onreadystatechange = function () { if(request.readyState ===4 || request.status ===200){ //将request.responseText返回的数据转化成JSON格式 var contacts = JSON.parse(request.responseText); //如果回调函数是function类型,则使用callback函数处理返回的JSON数据 if(callback === "function"){ callback(contacts); } } }; request.open("GET","data/ingredient.json",true); request.send(null); }
然後呼叫ajaxCall():
rrre然後調用ajaxCall():
Ajax 所對應的HTML文件://调用程序,我们将使用Ajax请求的JSON数据显示到HTML文档的某个区域中! (function () { "use strict"; //下面将给出DOM语句相对应的HTML代码 var searchForm = document.getElementById("search-form"), searchField = document.getElementById("q"), getAllButton = document.getElementById("get-all"), target = document.getElementById("output"); var search = { salad : function(event){ var output = document.getElementById("output"); //请求的JSON数据文件名,输出到HTML的区域,检索数据文件的核心function语句 ajaxCall('data/ingredient.json','output',function(data){ //searchValue为搜索条目,准备循环检索 var searchValue = searchField.value, //找到食材条目(详见JSON数据文件) fruit = data.fruit, //统计水果的数量 count = fruit.length, i; //阻止默认行为 event.preventDefault(); //初始化 target.innerHTML = ""; if(count > 0 || searchValue !==""){ for(i = 0;i < count;i++){ var obj = fruit[i], //将name与searchvalue值相匹配,如果值不等于 -1,那么就确定两者相匹配 inItfount = obj.name.indexOf(searchValue); //将JSON中匹配的数据规范的写入到DOM if(isItfount != -1){ target.innerHTML += '<p>'+obj.name+'<a href="mailto:" '+obj.color+'>'+obj.color+'</a></p>' } } } }) } }; //事件监听器,监听鼠标单击事件后调用函数并请求JSON数据文件 searchField.addEventListener("click",search.salad,false); })();