一、 Ajax ( asynchronousjavascript and xml )简介
- ajax不是一项具体的技术,而是Javascript、XHTML和CSS、DOM、XML和XMLHttpRequest等多门技术的综合应用。
- 作用:可以在用户浏览网页的同时与服务器进行异步交互和实现网页内容的局部更新。
- 核心:程序不通过浏览器发出请求,而是调用javascript中的类XMLHttpRequest对象来发送请求,再由这个JavaScript对象接收响应,并将响应结果用DOM编程方式挂到原来的网页上。
a. 浏览器的普通交互方式:
b. Ajax的交互方式:
同步与异步:
(1) 同步:是指发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
流程:提交请求->等待服务器处理->处理完毕返回(这个期间客户端浏览器不能干任何事)
(2) 异步:是指发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
流程:请求通过事件触发->服务器处理(这时浏览器仍然可以作其他事情)->处理完毕
二、Ajax框架的基本流程:
- XMLHttpRequest对象初始化
- 指定响应处理函数
- 发送Http请求
- 处理服务器返回的信息
1. 初始化XMLHttpRequest对象
XMLHttpRequest最早是在IE5中以ActiveX组件的形式实现的,非W3C标准.,所以XMLHttpRequest在不同浏览器上的实现方法不统一,但在不同浏览器上的实现是兼容的。
1.1 XMLHttpRequest对象属性:
(1) onreadychange: 通信状态改变的事件触发器,每次readyState属性的改变都会触发 readystatechange事件。
(2) readyState:通信状态,值为数值。 readyState 值的变化会因浏览器的不同而有所差异。但是,当请求结束的时候,每个浏览器都会把 readyState 的值统一设为 4 。
reayState值: a. 0 -- 未初始化 ( open 方法还没有被调用) b. 1 -- 正在加载 ( send 方法还没有被调用 ) c. 2 -- 已加载完毕 ( 请求已经开始 ) d. 3 -- 交互中 ( 服务器正在发送响应 ) e. 4 -- 完成 ( 响应发送完毕 ) |
(3) status: 服务器返回的状态码。
常用status状态码及其含义: a. 404 -- 没找到页面(not found) b. 403 -- 禁止访问(forbidden) c. 500 -- 内部服务器出错(internal service error) d. 200 -- 一切正常(ok) e. 304 -- 没有被修改(not modified)(服务器返回304状态,表示源文件没有被修改 ) |
(4) responseText: 从服务器发送的响应数据
注意: 只有当 readyState 属性值变成 4 时, responseText 属性才可用,表明 Ajax 请求已经结束。
(5) responseXML: 如果服务器返回的是 XML, 那么数据将储存在 responseXML 属性中。
注意: 只用服务器发送了带有正确首部信息的数据时, responseXML 属性才是可用的。所以,修改 MIME 类型为 text/xml (即contentType="text/xml")
(6) statusText:服务器返回的状态文本信息
1.2 XMLHttpRequest对象方法:
(1) abort(); -- 停止当前请求
(2) getAllResponseHeaders() ; -- 把http请求的所有响应首部作为键/值对返回
(3) getResponseHeader("headerLabel") ; -- 返回指定首部的串值
(4) open(“method”,”uri”,asynch); -- 建立对服务器的调用
第一个参数:HTTP请求方式。可以是GET或POST(按照HTTP规范,该参数要大写)。
第二个参数:请求页面的URL,可以是相对URL或绝对URL。
第三个参数:设置请求是否为异步模式,默认值为true(异步模式)。
注意:a .若只想从服务器检索一个文件,而不需要发送任何数据,使用GET(可以在GET请求里通过附加在URL上的查询字符串来发送数据,不过数据大小限制为2000个字符)。若需要向服务器发送数据,用POST。
b . 如果以POST方式请求,必须先调用setRequestHeader方法,修改MIME类别。 eg:xhr.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”);
(5) send(data); -- 向服务器发送请求。若采用的GET请求方式,send(null)就可以了(即使send非空值,服务器也接收不到)。
(6) setRequestHeader("head", "value") ; -- 设置指定首部数值。首部信息是一系列描述请求的元数据(metadata),首部信息用来声明一个请求是 GET 还是 POST方式。
第一个参数:首部的名字。
第二个参数:首部的值。
eg: // 声明POST请求
xhr.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”);
1.3 XMLHttpRequest对象初始化代码:
Function createXmlHttpRequest(){
var xmlhttp = null;
try{
//Firefox, Opera 8.0+, Safari直接new创建XMLHttpRequest对象
xmlhttp=new XMLHttpRequest();
}catch(e){
//IE7.0以下的浏览器以ActiveX组件的方式来创建XMLHttpRequest对象
var MSXML =
['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0',
'MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP','Microsoft.XMLHTTP'];
for(var n = 0; n < MSXML.length; n ++){
try{
xmlhttp = new ActiveXObject(MSXML[n]);
break;
}catch(e){}
}
}
return xmlhttp;
}
2. 指定响应处理函数
指定当服务器返回信息时客户端的处理方式.
(1) 首先,它要检查XMLHttpRequest对象的readyState值,判断目前的通信状态。
if (http_request.readyState == 4) {
// 信息已经返回,可以开始处理
} else {
// 信息还没有返回,等待
}
(2) 其次,还需要判断返回的HTTP状态码,确定返回的页面没有错误。
if (http_request.status == 200) {// 页面正常,可以开始处理信息
} else {
// 页面有问题
}
eg: var xhr = createXmlHttpRequest(); //XmlHttpRequest初始化
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if(xhr.status == 200 || xhr.status == 304){
alert(xhr.responseText);
}
}
}
3. 发出HTTP请求
这一步调用XMLHttpRequest对象的open和send方法。
eg: //GET请求方式
xhr.open('GET', 'checkUser.jsp?username='+name, true);
xhr.send(null)
//POST请求方式
xhr.open("post","checkUser.jsp",true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(name="+name+"&password=ppp"); <span style="font-size: 12.380952835083px; font-family: Arial, Helvetica, sans-serif;">//</span><span style="font-size: 12.380952835083px; font-family: Arial, Helvetica, sans-serif;">xhr.send("info={'username':'123456','password':'123456'}"); </span>
注意:xhr.setRequestHeader()要放在open()和send()之间。
4. 服务器处理信息
eg: // jsp中处理
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String username = request.getParameter("username"); //JSONObject jsonObj = new JSONObject(); JSONObject obj = jsonObj.fromObject(request.getParameter("info"));
if("admin".equals(username)){
out.print("用户名已存在");
}
else
{
out.print("用户名可以使用");
}
%>
// Servlet中处理
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
response.setCharacterEncoding("UTF-8");
if("admin".equals(username)){
response.getWriter().print("用户名已存在");
}
else
{
response.getWriter().print("用户名可以使用");
}
}
实例演示(异步检测用户名是否可用):
ajax.js :
function createXmlHttpRequest(){
var xmlhttp = null;
try{
//Firefox, Opera 8.0+, Safari直接new创建XMLHttpRequest对象
xmlhttp=new XMLHttpRequest();
}catch(e){
//IE7.0以下的浏览器以ActiveX组件的方式来创建XMLHttpRequest对象
var MSXML =
['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0',
'MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP','Microsoft.XMLHTTP'];
for(var n = 0; n < MSXML.length; n ++){
try{
xmlhttp = new ActiveXObject(MSXML[n]);
break;
}catch(e){}
}
}
if (!xmlhttp) { // 异常,创建对象实例失败
window.alert("不能创建XMLHttpRequest对象实例.");
}
return xmlhttp;
}
function userCheck(sendTagId,msgTagId)
{
var xhr = createXmlHttpRequest(); //XmlHttpRequest初始化
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if(xhr.status == 200 || xhr.status == 304){
document.getElementById(msgTagId).innerHTML = "<font color='red'>" + xhr.responseText + "</font>";
// alert(xhr.responseText);
}
}
}
var sendValue = document.getElementById(sendTagId).value;
xhr.open("post","user/isExists.action",true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send("name=" + sendValue);
}
register.jsp :
<script src="ajax.js"></script>
<body>
<s:form action="login" method="post" namespace="user">
<s:textfield name="name" id="name" label="用户名"/>
<!-- 用于异步检测用户名是否可用 -->
<a href="javascript:userCheck('name','msg');">检查用户名可用性</a>
<!-- 用于显示异步返回的结果 -->
<p id="msg"></p>
<s:password name="pwd" label="密码"></s:password>
<s:submit value="注册"></s:submit>
</s:form>
</body>
userAction :
public class UserAction extends ActionSupport implements ServletResponseAware, ModelDriven<User> {
private User user;
private HttpServletResponse response;
public HttpServletResponse getResponse() {
return response;
}
public void setResponse(HttpServletResponse response) {
this.response = response;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
//判断用户名是否已被占用
public void isExists() throws IOException
{
response.setContentType("text/json; charset=utf-8");
if(user.getName().equals("admin"))
{
response.getWriter().write("用户名已存在!");
}
else
{
response.getWriter().write("恭喜你,该用户名还未被占用!");
}
}
@Override
public User getModel() {
if(user == null)
{
user = new User();
}
return user;
}
@Override
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
}