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():
//调用程序,我们将使用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="https://www.jb51.net/mailto:" '+obj.color+'>'+obj.color+'</a></p>' } } } }) } }; //事件监听器,监听鼠标单击事件后调用函数并请求JSON数据文件 searchField.addEventListener("click",search.salad,false); })();
Ajax 所对应的HTML文档: