首页 > 编程笔记 > PHP笔记 阅读:15

Ajax是什么,PHP Ajax使用教程(非常详细,附带实例)

Ajax 是目前很新的一种网络技术。确切地说,Ajax 不只是一种技术,而是一种用于创建更好、更快以及交互性更强的 Web 应用程序的技术。它能使浏览器为用户提供更为自然的浏览体验,就像在使用桌面应用程序一样。

什么是Ajax

Ajax 的全称为 Asynchronous JavaScript And XML,是一种 Web 应用程序客户机技术,结合了 JavaScript、层叠样式表(Cascading Style Sheets,CSS)、HTML、XMLHttpRequest 对象和文档对象模型(Document Object Model,DOM)多种技术。

运行在浏览器上的 Ajax 应用程序以一种异步的方式与 Web 服务器通信,并且只更新页面的一部分。利用 Ajax 技术可以提供丰富的、基于浏览器的用户体验。

Ajax 让开发者在浏览器端更新被显示的 HTML 内容,而不必刷新页面。换句话说,Ajax 可以使基于浏览器的应用程序更具交互性,而且更类似于传统型桌面应用程序。Google 的 Gmail 和 Outlook Express 就是两个使用Ajax技术的例子。

而且,Ajax 可以用于任何客户端脚本语言中,包括 JavaScript、JScript 和 VBScript。

下面给出一个简单的实例来具体了解一下什么是 Ajax。

本实例从一个简单的角度入手,实现客户端与服务器的异步通信,获取“你好,Ajax”的数据,并在不刷新页面的情况下将获得的“你好,Ajax”数据显示到页面上,具体的步骤如下:
1) 使用记事本创建 HelloAjax.jsp 文件,代码如下:
<%@ page language="java" pageEncoding="gb2312"%>
<html>
<head>
<title>第一个 Ajax 实例</title>
<style type="text/css">
<!--
  body {
    background-image: url(images/img.jpg);
  }
-->
</style>
</head>
<script type="text/javascript">
//省略了 script 代码
</script>
<body><br/>
<center>
  <button onclick="hello()">Ajax</button>
  <p id="p">
    单击按钮后你会有惊奇的发现哟!
  </p>
</center>
</body>
</html>
JavaScript 代码嵌入在标签 <script></script> 之内,这里定义了一个函数 hello(),这个函数是通过按钮来驱动的。

2) 在步骤 1 省略的代码部分创建 XML Http Request 对象,创建完成后把此对象赋值给 xml Http 变量。为了获得多种浏览器的支持,应使用 create XML Http Request() 函数试着为多种浏览器创建 XmlHttpRequest 对象,代码如下:
var xmlHttp = false;
function createXMLHttpRequest() {
    if (window.ActiveXObject) { // 在 IE 浏览器中创建 XMLHttpRequest 对象
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch(e) {
            try {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            } catch(ee) {
                xmlHttp = false;
            }
        }
    } else if (window.XMLHttpRequest) { // 在非 IE 浏览器中创建 XMLHttpRequest 对象
        try {
            xmlHttp = new XMLHttpRequest();
        } catch(e) {
            xmlHttp = false;
        }
    }
}

3) 在步骤 1 省略的代码部分再定义 hello() 函数,hello() 函数为要与之通信的服务器资源创建一个 URL。

在“xmlHttp.onreadystatechange=callback;”与“xmlHttp.open("post","HelloAjaxDo. jsp",true);”代码中,前者定义了 JavaScript 回调函数,一旦响应就会自动执行,而第二个函数中所指定的 true 标志说明想要异步执行该请求,在没有指定的情况下默认为 true,代码如下:
function hello() {
    createXMLHttpRequest(); // 调用创建 XMLHttpRequest 对象的方法
    xmlHttp.onreadystatechange = callback; // 设置回调函数
    xmlHttp.open("post", "HelloAjaxDo.jsp", true);
    // 向服务器端 HelloAjaxDo.jsp 发送请求
    xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=gb2312");
    xmlHttp.send(null);
    function callback() {
        if (xmlHttp.readyState == 4) {
            if (xmlHttp.status == 200) {
                var data = xmlHttp.responseText;
                var pNode = document.getElementById("p");
                pNode.innerHTML = data;
            }
        }
    }
}
函数 callback() 是回调函数,首先检查 XMLHttpRequest 对象的整体状态以保证它已经完成(readyStatus==4),然后根据服务器的设定询问请求状态。如果一切正常(status==200),就使用“var data=xmlHttp.responseText;”取得返回的数据,用 innerHTML 属性重写 DOM 的 pNode 节点的内容。

JavaScript 的变量类型使用的是弱类型,都使用 var 来声明。document 对象就是文档对应的 DOM 树。通过“document.getElementById("p");”可以用一个标签的 id 值来取得此标签的一个引用(树的节点);“pNode.innerHTML=str;”为节点添加内容,这样就覆盖了节点的原有内容,如果不想覆盖,可以使用“pNode.innerHTML+=str;”来追加内容。

4) 通过步骤 3 可以知道接收异步请求的是 HelloAjaxDo.jsp,下面需要创建此文件,代码如下:
<%@ page language="java" pageEncoding="gb2312"%>
<%
    out.println("你好,Ajax");
%>

5) 将上述文件保存在 Ajax 站点下,启动 Tomcat 服务器并打开浏览器,在地址栏输入“http://localhost/ch19/HelloAjax.jsp”,单击【转到】按钮,结果如下图所示。


图 1 会变的页面

6) 单击 Ajax 按钮,发现变化,页面如下图所示。注意,按钮下方的内容发生了变化,这个变化没有刷新页面的过程。


图 2 动态改变页面

Ajax的关键元素

Ajax 不是单一的技术,而是 4 种技术的集合,要灵活地运用 Ajax 必须深入了解这些不同的技术,下表中列出了这些技术以及它们在 Ajax 中所扮演的角色。

表:Ajax 涉及的技术
技术名称 描述
JavaScript JavaScript 是通用的脚本语言,用来嵌入在某种应用之中。Web 浏览器中嵌入的 JavaScript 解释器允许通过程序与浏览器的很多内建功能进行交互。Ajax 应用程序是使用 JavaScript 编写的
CSS CSS 为 Web 页面元素提供了一种可重用的可视化样式的定义方法。它提供了简单而又强大的方法,以一致的方式定义和使用可视化样式。在 Ajax 应用中,用户界面的样式可以通过 CSS 独立修改
DOM DOM 以一组可以使用 JavaScript 操作的可编程对象展现出 Web 页面的结构。通过使用脚本修改 DOM,Ajax 应用程序可以在运行时改变用户界面,或者高效地重绘页面中的某个部分
XMLHttpRequest 对象 XMLHttpRequest 对象允许 Web 程序员在页面上以后台活动的方式从 Web 服务器获取数据。数据格式通常是 XML,但是也可以很好地支持任何基于文本的数据格式

Ajax 的 4 种技术当中,CSS、DOM 和 JavaScript 都是很早就出现的技术,它们以前结合在一起称为动态 HTML,即 DHTML。

Ajax 的核心是 JavaScript 对象 XMlHttpRequest。该对象在 Internet Explorer 5 中首次引入,是一种支持异步请求的技术。简而言之,XMlHttpRequest 使你可以使用 JavaScript 向服务器提出请求并处理响应,而不阻塞用户。

CSS与Ajax

CSS 在 Ajax 中主要用于美化网页,是 Ajax 的美术师。无论 Ajax 的核心技术采用什么形式,任何时候显示在用户面前的都是一个页面,是页面就需要美化,就需要使用 CSS 对显示在用户浏览器上的界面进行美化。

如果用户在浏览器中查看页面的源代码,就可以看到众多的 <div> 块以及 CSS 属性占据了源代码的大部分,如下图所示。从这一点可以看到 CSS 在页面美化方面的重要性。


图 3 源文件中的 CSS 代码

Ajax快速入门

Ajax 作为一项新技术,结合了 4 种不同的技术,实现了客户端与服务器端的异步通信,并且对页面实现局部更新,大大提高了浏览器显示 Web 信息的速度。

1、全面剖析XMLHttpRequest对象

1) XMLHttpRequest概述

XMLHttpRequest 对象是当今所有 Ajax 和 Web 2.0 应用程序的技术基础。尽管软件经销商和开源社区现在都在提供各种 Ajax 框架以进一步简化 XMLHttpRequest 对象的使用,但是,我们仍然很有必要了解这个对象的详细工作机制。

Ajax 利用一个构建到所有现代浏览器内部的对象 XMLHttpRequest 来实现发送和接收 HTTP 请求与响应信息。一个经由 XMLHttpRequest 对象发送的 HTTP 请求并不要求页面中拥有或回寄一个 <form> 元素。

微软 Internet Explorer(IE)5 中以一个 ActiveX 对象的形式引入了 XMLHttpRequest 对象。其他认识到这一对象重要性的浏览器制造商也纷纷在其浏览器内实现了 XMLHttpRequest 对象,但是作为一个本地 JavaScript 对象而不是作为一个 ActiveX 对象实现的。

如今,在认识到实现这一类型的价值及安全性特征之后,微软已经在其 IE 7 中把 XMLHttpRequest 实现为一个窗口对象属性。幸运的是,尽管其实现细节不同,但是,所有的浏览器实现都具有类似的功能,并且实质上是使用了相同的方法。目前,W3C 组织正在努力进行 XMLHttpRequest 对象的标准化。

2) XMLHttpRequest对象的属性和事件

XMLHttpRequest 对象暴露各种属性、方法和事件,以便于脚本处理和控制 HTTP 请求与响应。下面进行详细介绍。

① readyState属性

当 XMLHttpRequest 对象把一个 HTTP 请求发送到服务器时将经历若干种状态,一直等到请求被处理;然后,它才接收一个响应。这样一来,脚本才正确响应各种状态,XMLHttpRequest 对象暴露描述对象当前状态的是 readyState 属性,如下表所示。

表:XMLHttpRequest对象的readyState属性值列表
readyState 取值 描述
0 描述一种“未初始化”状态。此时,已经创建一个 XMLHttpRequest 对象,但是还没有初始化
1 描述一种“发送”状态,此时代码已经调用了 XMLHttpRequest 的 open()方法,并且 XMLHttpRequest 已经准备好把一个请求发送到服务器
2 描述一种“发送”状态。此时,已经通过 send()方法把一个请求发送到服务器端,但是还没有收到一个响应
3 描述一种“正在接收”状态。此时,已经接收到 HTTP 响应头部信息,但是消息体部分还没有完全接收结束
4 描述一种“已加载”状态。此时,响应已经被完全接收

② onreadystatechange事件

无论 readyState 值何时发生改变,XMLHttpRequest 对象都会激发一个 readystatechange 事件。其中,onreadystatechange 属性接收一个 EventListener 值,该值向该方法指示,无论 readyState 值何时发生改变,该对象都将激活。

③ responseText属性

这个 responseText 属性包含客户端接收到的 HTTP 响应的文本内容:

④ responseXML属性

responseXML 属性用于当接收到完整的 HTTP 响应时描述 XML 响应。此时,Content-Type 头部指定 MIME(媒体)类型为 text/xml、application/xml 或以 +xml 结尾。

如果 Content-Type 头部并不包含这些媒体类型之一,那么 responseXML 的值为 Null。无论何时,只要 readyState 值不为 4,那么该 responseXML 的值也为 Null。

其实,这个 responseXML 属性值是一个文档接口类型的对象,用来描述被分析的文档。如果文档不能被分析(例如,文档不是良构的或不支持相应的字符编码),那么 responseXML 的值将为 null。

⑤ status属性

status 属性描述了 HTTP 状态代码,其类型为 short。而且,仅当 readyState 值为 3(正在接收中)或 4(已加载)时,这个 status 属性才可用。当 readyState 的值小于 3 时,试图存取 status 的值将引发一个异常。

⑥ statusText属性

statusText 属性描述了 HTTP 状态代码文本,并且仅当 readyState 值为 3 或 4 时才可用。当 readyState 为其他值时,试图存取 statusText 属性将引发一个异常。

3) 创建XMLHttpRequest对象的方法

XMLHttpRequest 对象提供了各种方法用于初始化和处理 HTTP 请求,如下表所示。

方法 描述
abort() 用户可以使用 abort() 方法来暂停与一个 XMLHttpRequest 对象相联系的 HTTP 请求,从而把该对象复位到未初始化状态。
open() 用户需要调用 open() 方法来初始化一个 XMLHttpRequest 对象。其中,method 参数是必须提供的,用于指定你想用来发送请求的 HTTP 方法。为了把数据发送到服务器,应该使用 POST 方法;为了从服务器端检索数据,应该使用 GET 方法。
send() 在通过调用 open() 方法准备好一个请求之后,用户需要把该请求发送到服务器。仅当 readyState 值为 1 时,用户才可以调用 send() 方法;否则,XMLHttpRequest 对象将引发一个异常。
setRequestHeader() setRequestHeader() 方法用来设置请求的头部信息。当 readyState 值为 1 时,用户可以在调用 open() 方法后调用这个方法;否则,将得到一个异常。
getResponseHeader() getResponseHeader() 方法用于检索响应的头部值。仅当 readyState 值是 3 或 4(换句话说,在响应头部可用以后)时,才可以调用这个方法;否则,该方法返回一个空字符串。
getAllResponseHeaders() getAllResponseHeaders() 方法以一个字符串的形式返回所有的响应头部(每一个头部占单独的一行)。如果 readyState 的值不是 3 或 4,那么该方法返回 null。

2、发出Ajax请求

在 Ajax 中,许多使用 XMLHttpRequest 的请求都是从一个 HTML 事件中被初始化的。Ajax 支持包括表单校验在内的各种应用程序。

有时,在填充表单的其他内容之前要求校验一个唯一的表单域,例如要求使用一个唯一的 UserID 来注册表单。如果不使用 Ajax 技术来校验这个 UserID 域,那么整个表单都必须被填充和提交。如果该 UserID 不是有效的,那么这个表单必须被重新提交。

例如,一个对应于要求必须在服务器端进行校验的 Catalog ID 的表单域可按下列形式指定:
<form name="validationForm" action="validateForm" method="post">
<table>
<tr><td>Catalog Id:</td>
<td>
<input type="text" size="20" id="catalogId" name="catalogId" autocomplete="off"
    onkeyup="sendRequest()">
</td>
<td><div id="validationMessage"></div></td>
</tr>
</table></form>
前面的 HTML 使用 validationMessage div 来显示对应于这个输入域 Catalog Id 的一个校验消息。onkeyup 事件调用一个 JavaScript sendRequest() 函数。这个 sendRequest() 函数创建一个 XMLHttpRequest 对象,其创建 XMLHttpRequest 对象的过程因浏览器实现的不同而有所区别。

如果浏览器支持 XMLHttpRequest 对象作为一个窗口属性,那么代码可以调用 XMLHttpRequest 的构造器。如果浏览器把 XMLHttpRequest 对象实现为一个 ActiveXObject 对象,那么代码可以使用 ActiveXObject 的构造器。

下面的代码将调用一个 init() 函数。
<script type="text/javascript">
function sendRequest() {
  var xmlHttpReq = init();
  function init() {
    if (window.XMLHttpRequest) {
       return new XMLHttpRequest();
    }
    else if (window.ActiveXObject) {
       return new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
}
</script>
接下来用户需要使用 open() 方法初始化 XMLHttpRequest 对象,从而指定 HTTP 方法和要使用的服务器 URL。
var catalogId=encodeURIComponent(document.getElementById("catalogId").value);
xmlHttpReq.open("GET", "validateForm?catalogId=" + catalogId, true);
默认情况下,使用 XMLHttpRequest 发送的 HTTP 请求是异步进行的,但是用户可以显式地把 async 参数设置为 true。在这种情况下,对 URL validateForm 的调用将激活服务器端的一个 servlet。但是用户应该能够注意到服务器端的技术不是根本性的;实际上,该 URL 可能是一个 ASP、ASP.NET、PHP 页面或一个 Web 服务,只要该页面能够返回一个响应,指示 CatalogID 值是否有效即可。因为用户在做异步调用时,需要注册一个 XMLHttpRequest 对象来调用回调事件处理器,当它的 readyState 值改变时调用。

记住,readyState 值的改变将会激发一个 readystatechange 事件。这时可以使用 onreadystatechange 属性来注册该回调事件处理器。
xmlHttpReq.onreadystatechange=processRequest;

然后,需要使用 send() 方法发送该请求。因为这个请求使用的是 HTTP GET 方法,所以用户可以在不指定参数或使用 Null 参数的情况下调用 send() 方法。
xmlHttpReq.send(null);

3、处理服务器响应

在上述示例中,因为 HTTP 方法是 GET,所以在服务器端接收的 servlet 将调用一个 doGet() 方法,该方法将检索在 URL 中指定的 catalogId 参数值,并且从一个数据库中检查它的有效性。

该示例中的 servlet 需要构造一个发送到客户端的响应,而且这个示例返回的是 XML 类型,因此它把响应的 HTTP 内容类型设置为 text/xml,并且把 Cache-Control 头部设置为 no-cache。

设置 Cache-Control 头部可以阻止浏览器简单地从缓存中重载页面,具体的代码如下:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
    ...
    ...
   response.setContentType("text/xml");
   response.setHeader("Cache-Control", "no-cache");
}

从上述代码中可以看出,来自于服务器端的响应是一个 XML DOM 对象,此对象将创建一个 XML 字符串,其中包含需要在客户端进行处理的指令。另外,该 XML 字符串必须有一个根元素,代码如下:
out.println("<catalogId>valid</catalogId>");

XMLHttpRequest 对象设计的目的是为了处理由普通文本或 XML 组成的响应;但是,一个响应也可能是另一种类型,如果用户代理支持这种内容类型的话。

当请求状态改变时,XMLHttpRequest 对象调用使用 onreadystatechange 注册的事件处理器。因此,在处理该响应之前,用户的事件处理器应该首先检查 readyState 的值和 HTTP 状态。当请求完成加载(readyState 值为 4)并且响应已经完成(HTTP 状态为 OK)时,用户就可以调用一个 JavaScript 函数来处理该响应内容。

下面的脚本负责在响应完成时检查相应的值并调用一个 processResponse() 方法。
function processRequest() {
    if (xmlHttpReq.readyState == 4) {
        if (xmlHttpReq.status == 200) {
            processResponse();
        }
    }
}
该 processResponse() 方法使用 XMLHttpRequest 对象的 responseXML 和 responseText 属性来检索 HTTP 响应。如上面所解释的,仅当在响应的媒体类型是 text/xml、application/xml 或以 +xml 结尾时,这个 responseXML 才可用。这个 responseText 属性将以普通文本形式返回响应。

对于一个 XML 响应,用户将按如下方式检索内容:
var msg=xmlHttpReq.responseXML;

借助于存储在 msg 变量中的 XML,用户可以使用 DOM 方法 getElementsByTagName() 来检索该元素的值,代码如下:
var catalogId=msg.getElementsByTagName("catalogId")[0].firstChild.nodeValue;

最后,通过更新 Web 页面的 validationMessage div 中的 HTML 内容并借助于 innerHTML 属性,用户可以测试该元素值以创建一个要显示的消息,代码如下:
if(catalogId=="valid"){
    var validationMessage = document.getElementById("validationMessage");
    validationMessage.innerHTML = "Catalog Id is Valid";
}
else
{
   var validationMessage = document.getElementById("validationMessage");
   validationMessage.innerHTML = "Catalog Id is not Valid";
}

使用Ajax开发商品实时搜索功能

Ajax 综合了各个方面的技术,不但能够加快用户的访问速度,还可以实现各种功能。本实例将开发一个实时搜索功能,当输入数据的同时即可得到搜索结果。

这里需要三个文件来实现商品实时搜索功能,这里分别是 19.1.xml、19.1.html 和 19.1.php。

首先创建 19.1.xml,用于存储商品的信息,代码如下:
<pages>
  <link>
    <title>蓝色的冰箱</title>
    <url>价格为 4689 元</url>
  </link>
  <link>
    <title>蓝色的洗衣机</title>
    <url>价格为 1689 元</url>
  </link>
  <link>
    <title>蓝色的空调</title>
    <url>价格为 8689 元</url>
  </link>
  <link>
    <title>红色的冰箱</title>
    <url>价格为 1689 元</url>
  </link>
  <link>
    <title>红色的洗衣机</title>
    <url>价格为 2689 元</url>
  </link>
  <link>
    <title>白色的洗衣机</title>
    <url>价格为 6689 元</url>
  </link>
</pages>

接着创建 19.1.html,用于显示商品搜索页面,代码如下:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>实时查询功能</title>
<script>
  function showResult(str) {
    if (str.length == 0) {
      document.getElementById("livesearch").innerHTML = "";
      document.getElementById("livesearch").style.border = "0px";
      return;
    }
    if (window.XMLHttpRequest) {
      // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行
      xmlHttp = new XMLHttpRequest();
    } else {
      // IE6, IE5 浏览器执行
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlHttp.onreadystatechange = function() {
      if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
        document.getElementById("livesearch").innerHTML = xmlHttp.responseText;
        document.getElementById("livesearch").style.border = "1px solid #A5ACB2";
      }
    }
    xmlHttp.open("GET", "19.1.php?q=" + str, true);
    xmlHttp.send();
  }
</script>
</head>
<body>
<form>
  <h2 align="center">实时搜索功能</h2>
  <input type="text" size="30" onkeyup="showResult(this.value)">
  <div id="livesearch"></div>
</form>
</body>
</html>

最后创建 19.1.php,用于实现实时搜索功能,代码如下:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("19.1.xml");

$x = $xmlDoc->getElementsByTagName('link');

// 从 URL 中获取参数 q 的值
$q = $_GET["q"];

// 如果 q 参数存在则从 xml 文件中查找数据
if (strlen($q) > 0) {
    $hint = "";
    for ($i = 0; $i < $x->length; $i++) {
        $y = $x->item($i)->getElementsByTagName('title');
        $z = $x->item($i)->getElementsByTagName('url');
        if ($y->item(0)->nodeType == 1) {
            // 找到匹配搜索的链接
            if (strstr($y->item(0)->childNodes->item(0)->nodeValue, $q)) {
                if ($hint == "") {
                    $hint = "<a href='" .
                        $z->item(0)->childNodes->item(0)->nodeValue .
                        "' target='_blank'>" .
                        $y->item(0)->childNodes->item(0)->nodeValue . "</a>";
                } else {
                    $hint .= "<br /><a href='" .
                        $z->item(0)->childNodes->item(0)->nodeValue .
                        "' target='_blank'>" .
                        $y->item(0)->childNodes->item(0)->nodeValue . "</a>";
                }
            }
        }
    }
    // 如果没找到则返回 "no suggestion"
    if ($hint == "") {
        $response = "查不到相关内容哦!";
    } else {
        $response = $hint;
    }
    // 输出结果
    echo $response;
}
?>
运行程序 19.1.html,输入需要搜索的内容,将会对结果进行过滤,运行结果如下图所示。


图 4 显示匹配的结果

如果最终找不到匹配的结果,则显示信息“查不到相关内容哦!”,如下图所示。


图 5 找不到匹配的结果

相关文章