`

Ajax入门

    博客分类:
  • Ajax
阅读更多

 

Ajax技术的背景:

说到Ajax技术,就不得不说Google这个牛叉的公司了,我们知道,正式由于Google推出的Google EarthGoogle suggest以及gmail等,催生了Ajax成为今天的格局。据说因此让微软感到无比的悲剧,因为早在97年,微软便已经okAjax中的关键技术,并且在99年推出IE5时,便开始支持XmlHttpRequest对象,但是微软竟然没有看到Ajax的前景,估计是因为当时搞倒了Netscape公司,使得微软变得麻痹迟钝了。往往IT公司的一次不经意的打盹成就了另一个公司,当然现在的微软也重视起Ajax,比如现在推出它自己的ajax框架atlas,并且在.NET2.0也提供了一个用来实现异步回调的接口,即ICallBack接口。

 

Ajax技术的意义:

       作为Web程序员,我们可以回想一下,在自己的项目开发中有谁能够不去用Ajax?所以说Ajax技术应用现在已经很广泛了,其实说到Ajax所产生的意义,给我们第一个想法就是提升了用户的体验,yes,但是如果我们结合着将来电脑和互联网的发展趋势,我们会发现其实Ajax技术在某些方面正好代表了这种趋势。这怎么理解呢?我们知道在电脑刚刚兴起的时候,大家电脑上用的最多的就是桌面程序(C/S),而现在越来越多的是(B/S),而且在不久的将来,我们直接可以将硬盘里的东西放到互联网上,加上现在HTML5的出现,以后我们可以设想一下,基本上本子上直接安装一个浏览器,那么一切ok,甚至连操作系统都不需要了,(想想看似还是很遥远,但是如果HTML5发展的足够好,在现在这个IT技术飞速发展的时代,技术所能实现的功能只有你想不到的,没有做不到的,有点偏了)那么这其中存在着一个致命的问题就是互联网的连接不稳定。这样大家看着自己的本子从服务器上一点点的下载数据,应该是非常郁闷的。那么Ajax是不是ok这种问题呢?与其说Ajax是解决了这个问题,倒不如说它只是掩盖了这个问题。它只是在服务器和客户端之间充当了一个缓冲器,让用户误以为服务没有中断。精确的说,ajax并不能提高从服务器端下载数据的速度,而只是使这个等待不那么令人沮丧。但是正是这一点就足以产生巨大的影响和震动,它实际上也对桌面软件产生了巨大的冲击。

 

Ajax的名字:

ajax 的全称是Asynchronous JavaScript and XML,其中,Asynchronous 是异步的意思,它有别于传统web开发中采用的同步的方式(关于同步与异步的说明可以看我博客的这篇文章)。

 

Ajax所包含的技术:

大家在学习和使用Ajax的过程中都知道,Ajax并不是一门新的技术,而是几种原有技术的结合体:

       使用CSSXHTML来表示;

    使用DOM模型来交互和动态显示;

    使用XMLHttpRequest来和服务器进行异步通信。

    使用javascript来绑定和调用;

在上面几中技术中,除了XmlHttpRequest对象以外,其它所有的技术都是基于web标准并且已经得到了广泛使用的,XMLHttpRequest虽然目前还没有被W3C所采纳,但是它已经是一个事实的标准,因为目前几乎所有的主流浏览器都支持它。

 

Ajax原理和XmlHttpRequest对象:

Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。

XMLHttpRequestajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到局部刷新的效果(网上一些说无刷新是不严谨的)。

所以我们先从XMLHttpRequest讲起,来看看它的工作原理。

首先,我们先来看看XMLHttpRequest这个对象的属性。

属性

描述

onreadystatechange

每次状态改变所触发事件的事件处理程序。

responseText

从服务器进程返回数据的字符串形式。

responseXML

从服务器进程返回的DOM兼容的文档数据对象。

status

从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)

status Text

伴随状态码的字符串信息

readyState

对象状态值

对象状态值:

readyState

含义

0 (未初始化)

对象已建立,但是尚未初始化(尚未调用open方法)

1 (初始化)

对象已建立,尚未调用send方法

2 (发送数据)

send方法已调用,但是当前的状态及http头未知

3 (数据传送中)

已接收部分数据,因为响应及http头不全,这时通过responseBodyresponseText获取部分数据会出现错误

4 (完成)

数据接收完毕,此时可以通过通过responseXmlresponseText获取完整的回应数据

但是,由于各浏览器之间存在差异,所以创建一个XMLHttpRequest对象可能需要不同的方法。这个差异主要体现在IE和其它浏览器之间。下面是一个比较标准的创建XMLHttpRequest对象的方法。

Login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<title>用户登陆</title>
<script type="text/javascript">
	//获取不同浏览器下的Ajax引擎
	function getHttpRequest() {
		var httpRequest;
		//非IE浏览器创建XmlHttpRequest对象  ,如Firefox, Opera 8.0+, Safari...
		if (window.XmlHttpRequest) {
			httpRequest = new XmlHttpRequest();
		}
		//IE浏览器创建XmlHttpRequest对象  
		if (window.ActiveXObject) {
			try {
				httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {
				try {
					httpRequest = new ActiveXObject("msxml2.XMLHTTP");
				} catch (ex) {
				}
			}
		}
		return httpRequest;
	}

	function doAjaxLogin() {
		var httpRequest = getHttpRequest();//获取不同浏览器下的Ajax引擎对象
		if (!httpRequest) {//如果各个浏览器下都取不倒Ajax引擎对象,则说明该浏览器下不支持,所以这时还使用submit方式
			document.getElementById("loginForm").submit();
			return;
		}
		httpRequest.open("POST", "AjaxLoginServlet", true);//注意这里的URL必须是本域名下的
		//因为上面是POST提交方式,所以需要设置头信息,如果不设置,则取不倒值,如果是GET提交方式,则不需要设置
		httpRequest.setRequestHeader("Content-Type",
				"application/x-www-form-urlencoded");
		var data = "name=" + document.getElementById("name").value
				+ "&password=" + document.getElementById("password").value;
		httpRequest.send(data);
		var loginInfo = document.getElementById("loginInfo");
		httpRequest.onreadystatechange = function() {
			/*
				0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法) 
				1 (初始化) 对象已建立,尚未调用send方法 
				2 (发送数据) send方法已调用,但是当前的状态及http头未知 
				3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误, 
				4 (完成) 数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据 
			 */
			loginInfo.innerHTML = loginInfo.innerHTML + "<br />"
					+ "AjavxState:" + httpRequest.readyState;
			//readyState 属性存有服务器响应的状态信息。每当 readyState 改变时,onreadystatechange 函数就会被执行。

			if (httpRequest.readyState == 4) {
				loginInfo.innerHTML = loginInfo.innerHTML + "<h1 >"
						+ httpRequest.responseText + "</h1>";// responseText 属性来取回由服务器返回的数据
				if (httpRequest.responseText == "false") {
				} else if (httpRequest.responseText == "success") {
					window.location = "http://www.baidu.com";
				}

			}
		}
	}
</script>
</head>
<body>
	<h1>用户登陆</h1>
	<hr />
	<div id="loginInfo"></div>
	<%
		String msg = (String) session.getAttribute("msg");
		session.removeAttribute("msg");
		msg = (msg == null) ? "" : msg;
	%>
	<%=msg%>
	<form action="LoginServlet" method="post">
		<table>
			<tr>
				<td><label for="name">账号:</label></td>
				<td><input type="text" name="name" id="name" /></td>
			</tr>
			<tr>
				<td><label for="password">密码:</label></td>
				<td><input type="password" name="password" id="password" /></td>
			</tr>
			<tr>
				<td></td>
				<!-- 
		<td><input type="submit" value="登陆" onclick=""/></td>
		 -->
				<td><input type="button" value="登陆" onclick="doAjaxLogin()" /></td>
			</tr>

		</table>
	</form>
</body>
</html>

 通过上面可以看出函数首先检查XMLHttpRequest的整体状态并且保证它已经完成(readyStatus=4),即数据已经发送完毕。然后根据服务器的设定询问请求状态,如果一切已经就绪(status=200),那么就执行下面需要的操作。

 

对于XmlHttpRequest的两个方法,opensend,其中open方法指定了:

    向服务器提交数据的类型,即post还是get

    请求的url地址和传递的参数。

    传输方式,false为同步,true为异步。默认为true。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。我们需要根据实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式。

Send方法用来发送请求。

知道了XMLHttpRequest的工作流程,我们可以看出,XMLHttpRequest是完全用来向服务器发出一个请求的,它的作用也局限于此,但它的作用是整个ajax实现的关键,因为ajax无非是两个过程,发出请求和响应请求。并且它完全是一种客户端的技术。而XMLHttpRequest正是处理了服务器端和客户端通信的问题所以才会如此的重要。

AjaxLoginServlet.java:

package com.hms.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.hms.entity.User;

/**
 * 
 * @author xudongwang 2012-1-12
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class AjaxLoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public AjaxLoginServlet() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String name = request.getParameter("name");
		String password = request.getParameter("password");

		User user = new User();
		user.setName(name);
		user.setPassword(password);
		String msg = "false";

		if ("xudongwang".equals(name) && "123".equals(password)) {
			request.getSession().setAttribute("user", user);
			msg = "success";
		}
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/plain");
		response.getWriter().print(msg);
	}

}

 

User.java:

package com.hms.entity;

/**
 * @author xudongwang 2012-1-12
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class User {
	private String name;
	private String password;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

 

Ajax的优点:

    1、最大的一点是页面局部刷新,在页面内与服务器通信,给用户的体验非常好。

    2、使用异步方式与服务器通信,不需要打断用户的操作,具有更加迅速的响应能力。

    3、可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。

    4、基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。

 

Ajax的缺点:

下面简单归纳一下Ajax的缺陷,因为平时我们大多注意的都是Ajax给我们所带来的好处诸如用户体验的提升。而对Ajax所带来的缺陷有所忽视。

1Ajax干掉了back按钮

Ajax干掉了back按钮,即对浏览器后退机制的破坏。后退按钮是一个标准的web站点的重要功能,但是它没法和js进行很好的合作。这是ajax所带来的一个比较严重的问题,因为用户往往是希望能够通过后退来取消前一次操作的。那么对于这个问题有没有办法?答案是肯定的,用过Gmail的知道,Gmail下面采用的ajax技术解决了这个问题,在Gmail下面是可以后退的,但是,它也并不能改变ajax的机制,它只是采用的一个比较笨但是有效的办法,即用户单击后退按钮访问历史记录时,通过创建或使用一个隐藏的IFRAME来重现页面上的变更。(例如,当用户在Google Maps中单击后退时,它在一个隐藏的IFRAME中进行搜索,然后将搜索结果反映到Ajax元素上,以便将应用程序状态恢复到当时的状态。) 但是,虽然说这个问题是可以解决的,但是它所带来的开发成本是非常高的,和ajax框架所要求的快速开发是相背离的。这是ajax所带来的一个非常严重的问题。

2、安全问题

技术同时也对IT企业带来了新的安全威胁,ajax技术就如同对企业数据建立了一个直接通道。这使得开发者在不经意间会暴露比以前更多的数据和服务器逻辑。ajax的逻辑可以对客户端的安全扫描技术隐藏起来,允许黑客从远端服务器上建立新的攻击。还有ajax也难以避免一些已知的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于credentials的安全漏洞等。

3、对搜索引擎的支持比较弱

4、破坏了程序的异常机制

 

0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics