详解Ajax技术
Ajax 能够做什么? 如今 Google Suggest 和 Google Maps 使用了 Ajax,通过 Ajax,我们可以使得客户端得到丰富的应用体验及交换操作,而用户不会感觉到有网页提交或刷新的过程,页面也不需要被重新加载,应用的数据交换都被隐藏。
1、通过适当的Ajax应用达到更好的用户体验;
2、把以前的一些服务器负担的工作 转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担,从而达到节约ISP的空间及带宽租用成本的目的。 AJAX从哪里来的? Ajax这个概念的最早提出者Jesse James Garrett认为: Ajax是 Asynchronous JavaScript and XML的缩写。 Ajax并不是一门新的语言或技术,它实际上是几项技术按一定的方式组合在一在同共的协作中发挥各自的作用,它包括:
Ajax的
工作原理相当于在用户和服务器之间加了—个
中间层,使用户操作与服务器响应
异步化。并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做,只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。
AJAX的核心技术有哪些? 虽然Garrent列出了7条Ajax的构成技术,但个人认为,所谓的Ajax其 核心只有 JavaScript、XMLHTTPRequest和DOM,如果所用数据格式为XML的话,还可以再加上XML这一项(Ajax从服务器端返回的数据可以是XML格式,也可以是文本等其他格式)。 在旧的交互方式中,由用户触发一个HTTP请求到服务器,服务器对其进行处理后再返回一个新的HTHL页到客户端,每当服务器处理客户端提交的请求时,客户都只能空闲等待,并且哪怕只是一次很小的交互、只需从服务器端得到很简单的一个数据,都要返回一个完整的HTML页,而用户每次都要浪费时间和带宽去重新读取整个页面。 而使用Ajax后用户从感觉上几乎所有的操作都会很快响应没有页面重载(白屏)的等待。
XMLHttpRequest简称XmlHttp
它是一套可以在Javascript、VbScript、Jscript等脚本语言中通过http协议传送或从接收XML及其他数据的一套API。XmlHttp最大的用处是可以更新网页的部分内容而不需要刷新整个页面。
现在的绝对多数浏览器都增加了对XmlHttp的支持,IE中使用ActiveXObject方式创建XmlHttp对象,其他浏览器如:Firefox、Opera等通过window.XMLHttpRequest来创建xmlhttp对象。 属性:
着重介绍下
readyState属性
返回XMLHTTP请求的当前状态,每个数值代表一个状态
方法:
如何正确使用Ajax?
这里我们拿一个项目中常用的用户注册校验是否有重复用户名存在的案例来演示。并分别用get方式回传json,post方式回传json,post方式回传xml来演示。
首先我们得考虑在不同浏览器下如何获得
XmlHttp对象
function creatXmlHttpRequest() { if (typeof XMLHttpRequest != 'undefined') { return new XMLHttpRequest(); } else if (typeof ActiveXObject != 'undefined') { var MSXML = ['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP']; for (var i = 0; MSXML.length; i ++) { try{ return new ActiveXObject(version[i]); }catch (e) { //....... } } } else { throw new Error('您的系统或浏览器不支持XHR对象!'); } } GET方式回传json function checkUserByAjaxGet() { // 第一步,得到一个XMLHttpRequest对象 // var xhr=new XMLHttpRequest(); // 如果说IE6,就需要使用Active组建 // xmlhttp=new ActiveXObject(MSXML[n]); var xhr = creatXmlHttpRequest(); var name = document.rgform.username.value; // 设置一个事件的监听函数 xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200 || xhr.status == 304) { var ret = xhr.responseText; var _ret = eval('(' + ret + ')'); // var _ret = JSON.parse(ret); document.getElementById("msg").innerHTML = _ret.tip; if (_ret.success = true) { document.rgform.username.focus(); } } } } // 第二步,准备一个连接请求 xhr.open("get","checkuserByJSON.jsp?name=" + name,true); // 第三步,发起请求 xhr.send(null); } POST方式回传json function checkUserByAjaxPost() { // 第一步,创建xhr对象 var xhr = creatXmlHttpRequest(); var name = document.rgform.username.value; // 第二步,设置一个事件的监听函数 xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200 || xhr.status == 304) { var ret = xhr.responseText; var _ret = eval('(' + ret + ')'); // var _ret = JSON.parse(ret); document.getElementById("msg").innerHTML = _ret.tip; if (_ret.success = true) { document.rgform.username.focus(); alert(xhr.getResponseHeader("Content-Length")); alert(xhr.getResponseHeader("Content-Type")); alert(xhr.getResponseHeader("Date")); alert(xhr.getResponseHeader("Server")); } } } } // 第三步,准备一个POST连接请求 xhr.open("post","checkuserByJSON.jsp",true); // 使用post方式提交,必须要加上如下一行 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); // 第四步,发起请求 xhr.send("name=" + name + "&password=ppppp"); } POST方式回传xml function checkUserByAjaxPostXml() { // 第一步,设置一个事件的监听函数 xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200 || xhr.status == 304) { var ret = xhr.responseXML; var successNode = ret.getElementsByTagName("success")[0]; var tipNode = ret.getElementsByTagName("tip")[0]; document.getElementById("msg").innerHTML = tipNode.firstChild.nodeValue; if (successNode.firstChild.nodeValue == true) { document.rgform.username.focus(); } } } } // 第三步,"checkuserByXML.jsp",true); xhr.setRequestHeader("Content-Type",发起请求 xhr.send("name=" + name + "&password=ppppp"); } 返回的的json <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ page import="java.util.*" %> <% String username = request.getParameter("username"); response.setContentType("application/json;charset=UTF-8"); response.setHeader("pragma","no-cache"); response.setHeader("cache-control","no-cache"); if("admin".equals(username)) { response.getWriter().write("{"success":"+true+","tip":"用户名已存在"}"); } else { response.getWriter().write("{"success":"+false+","tip":"用户名可以使用"}"); } %> 返回的xml <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ page import="java.util.*" %> <% String userId = request.getParameter("name"); response.setContentType("application/xml;charset=UTF-8"); response.setHeader("pragma","no-cache"); if("admin".equals(userId)) { response.getWriter().write("<root><success>true</success><tip>用户名已存在</tip></root>"); } else { response.getWriter().write("<root><success>false</success><tip>用户名可以使用</tip></root>"); } %> 界面 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>register.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="js/register.js"></script> <script type="text/javascript" src="js/jquery-1.5.2.js"></script> <style type="text/css"> #round { padding:10px; width:300px; height:150px; border:1px solid #000; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px; margin:10px auto; } #round div.user,#round div.pass { font-size:14px; color:#666; padding:15px 0; text-align:center; position: relative; } #round span{ position: absolute; color:red; top:35px; left:100px; } #round input.text { width:200px; height:25px; border:1px solid #ccc; background:#fff; font-size:14px; } #round .button { padding:5px 0; text-align:center; } </style> </head> <body> <div id="round"> <form name="rgform" method="post" action="" > <div class="user"> 用户名:<input type="text" name="username" id="username" onchange="事件调用的方法"> <span id="msg"></span> </div> <div class="pass"> 密码:<input type="password" name="password" id="password"> </div> <div class="button"><input type="button" value="提交"/></div> </form> </div> </body> </html> 效果图
使用过jQuery异步请求的方法的同学,肯定觉得那个相当好用,相比而言,上面写的相当繁琐,get方式和post方式请求甚至还有部分代码是有很大区别的,那应如何通过代码的方式屏蔽这些区别呢,这里我们仿一下jQuery 的$.ajax() 方法。
//封装ajax function ajax(obj) { var xhr = creatXmlHttpRequest(); obj.url = obj.url + '?rand=' + Math.random(); obj.data = params(obj.data); if (obj.method === 'get') obj.url += obj.url.indexOf('?') == -1 ? '?' + obj.data : '&' + obj.data; if (obj.async === true) { xhr.onreadystatechange = function () { if (xhr.readyState == 4) { callback(); } }; } xhr.open(obj.method,obj.url,obj.async); if (obj.method === 'post') { xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send(obj.data); } else { xhr.send(null); } if (obj.async === false) { callback(); } function callback() { if (xhr.status == 200) { obj.success(xhr.responseText); //回调传递参数 } else { alert('获取数据错误!错误代号:' + xhr.status + ',错误信息:' + xhr.statusText); } } } //名值对转换为字符串 function params(data) { var arr = []; for (var i in data) { arr.push(encodeURIComponent(i) + '=' + encodeURIComponent(data[i])); } return arr.join('&'); } 调用我们封装的ajax方法 window.onload = function(){ document.getElementById("username").onchange = function(){ ajax({ method : 'post',url : 'checkuserByJSON.jsp',data : { 'username' : document.rgform.username.value,'password' : document.rgform.password.value },success : function (text) { var _ret = eval('(' + text + ')'); document.getElementById("msg").innerHTML = _ret.tip; },async : true }); } }我们给ajax传的就是一个object对象,是不是已经很贴近jQuery的方式了呢。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |