JAVASCRIPT 基础教程
JAVASCRIPT & DOM
JAVASCRIPT & BOM
JAVASCRIPT 高级教程
JAVASCRIPT 示例
JAVASCRIPT 参考

JavaScript Ajax

在本教程中,您将了解 Ajax 是什么以及如何在 JavaScript 中实现它。

什么是 Ajax?

Ajax 代表 Asynchronous Javascript And Xml。 Ajax 只是一种从服务器加载数据并有选择地更新网页部分而不重新加载整个页面的方法。

基本上,Ajax 所做的是利用浏览器的内置 XMLHttpRequest (XHR) 对象在后台异步向 Web 服务器发送和接收信息,而不会阻塞页面或干扰 用户体验。

Ajax 变得如此流行,以至于您几乎找不到在某种程度上不使用 Ajax 的应用程序。 一些大型 Ajax 驱动的在线应用程序的示例有:Gmail、Google Maps、Google Docs、YouTube、Facebook、Flickr 和许多其他应用程序。

注意: Ajax 并不是一种新技术,事实上,Ajax 甚至根本不是真正的技术。 Ajax 只是一个术语,用于描述通过 JavaScript 从 Web 服务器异步交换数据的过程,无需刷新页面。

提示:不要对 AJAX 中的术语 X(即 XML)感到困惑。 它只是出于历史原因而存在。 可以使用 JSON、HTML 或纯文本等其他数据交换格式来代替 XML。

了解 Ajax 的工作原理

为了执行 Ajax 通信,JavaScript 使用了一个内置在浏览器中的特殊对象——一个 XMLHttpRequest (XHR) 对象—向服务器发出 HTTP 请求并接收数据作为响应。

所有现代浏览器(Chrome、Firefox、IE7+、Safari、Opera)都支持 XMLHttpRequest 对象。

以下插图演示了 Ajax 通信的工作原理:

Ajax 插图

由于 Ajax 请求通常是异步的,因此一旦发送 Ajax 请求,脚本就会继续执行,即浏览器不会停止脚本执行,直到服务器响应返回。

在下一节中,我们将一一讨论此过程中涉及的每个步骤:

发送请求并获取响应

在客户端和服务器之间进行Ajax通信之前,首先要做的是实例化一个XMLHttpRequest对象,如下所示:

var request = new XMLHttpRequest();

现在,向服务器发送请求的下一步是使用 XMLHttpRequest 对象的 open() 方法实例化新创建的请求对象。

open() 方法通常接受两个参数— 要使用的 HTTP 请求方法,例如"GET"、"POST"等,以及将请求发送到的 URL,如下所示:

request.open("GET", "info.txt"); -Or- request.open("POST", "add-user.asp");

提示: 文件可以是任何类型的文件,例如 .txt.xml,也可以是服务器端脚本文件,例如 .asp.asp,它可以在将响应发送回客户端之前在服务器上执行一些操作(例如,从数据库中插入或读取数据)。

最后使用 XMLHttpRequest 对象的 send() 方法将请求发送到服务器。

request.send(); -Or- request.send(body);

注意: send() 方法接受一个可选的 body 参数,它允许我们指定请求的正文。 这主要用于 HTTP POST 请求,因为 HTTP GET 请求没有请求正文,只有请求标头。

GET 方法一般用于向服务器发送少量数据。 而 POST 方法用于发送大量数据,例如表单数据。

在 GET 方法中,数据作为 URL 参数发送。 但是,在 POST 方法中,数据作为 HTTP 请求正文的一部分发送到服务器。 通过 POST 方法发送的数据在 URL 中不可见。

有关这两种方法的详细比较,请参阅HTTP GET 与 POST 章节。

在下一节中,我们将仔细研究 Ajax 请求的实际工作方式。

执行 Ajax GET 请求

GET 请求通常用于从服务器获取或检索某种不需要对数据库进行任何操作或更改的信息,例如,根据术语获取搜索结果,根据用户 ID 获取用户详细信息 或姓名等。

以下示例将向您展示如何在 JavaScript 中发出 Ajax GET 请求。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Ajax GET Demo</title>
<script>
function displayFullName() {
    // 创建 XMLHttpRequest 对象
    var request = new XMLHttpRequest();

    // 实例化请求对象
    request.open("GET", "greet.asp?fname=John&lname=Clark");

    // 为 readystatechange 事件定义事件监听器
    request.onreadystatechange = function() {
        // 检查请求是否已完成并成功
        if(this.readyState === 4 && this.status === 200) {
            // 将来自服务器的响应插入 HTML 元素
            document.getElementById("result").innerHTML = this.responseText;
        }
    };

    // 向服务器发送请求
    request.send();
}
</script>
</head>
<body>
    <div id="result">
        <p>Content of the result DIV box will be replaced by the server response</p>
    </div>
    <button type="button" onclick="displayFullName()">Display Full Name</button>
</body>
</html>

当请求为异步时,send() 方法在发送请求后立即返回。 因此,在使用 XMLHttpRequest 对象的 readyState 属性处理响应之前,您必须检查响应当前在其生命周期中的位置。

readyState 是一个整数,用于指定 HTTP 请求的状态。 此外,分配给 onreadystatechange 事件处理程序的函数会在每次 readyState 属性更改时调用。 readyState 属性的可能值总结如下。

状态 说明
0 UNSENT XMLHttpRequest 对象已创建,但尚未调用 open() 方法(即请求未初始化)。
1 OPENED open() 方法已被调用(即服务器连接建立)。
2 HEADERS_RECEIVED send() 方法已被调用(即服务器已收到请求)。
3 LOADING 服务器正在处理请求。
4 DONE 请求已被处理,响应已准备就绪。

注意:理论上,readystatechange 事件应该在每次 readyState 属性改变时触发。 但是,当 readyState 更改为 0 或 1 时,大多数浏览器不会触发此事件。但是,当 readyState 更改为 4 时,所有浏览器都会触发此事件。

status 属性返回 XMLHttpRequest 响应的数字 HTTP 状态代码。 下面列出了一些常见的 HTTP 状态代码:

  • 200 — OK. 服务器成功处理了请求。
  • 404 — Not Found. 服务器找不到请求的页面。
  • 503 — 暂停服务。 服务器暂时不可用。

请查看 HTTP 状态代码 参考以获取完整的响应代码列表。

这是我们的"greet.asp"文件中的代码,它通过连接一个人的名字和姓氏来简单地创建一个人的全名,并输出一条问候消息。

示例

Download
<?php
if(isset($_GET["fname"]) && isset($_GET["lname"])) {
    $fname = htmlspecialchars($_GET["fname"]);
    $lname = htmlspecialchars($_GET["lname"]);
    
    // 通过连接名字和姓氏来创建全名
    $fullname = $fname . " " . $lname;

    // 显示欢迎信息
    echo "Hello, $fullname! Welcome to our website.";
} else {
    echo "Hi there! Welcome to our website.";
}
?>

执行 Ajax POST 请求

POST 方法主要用于向 Web 服务器提交表单数据。

下面的示例将向您展示如何使用 Ajax 向服务器提交表单数据。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Ajax POST Demo</title>
<script>
function postComment() {
    // 创建 XMLHttpRequest 对象
    var request = new XMLHttpRequest();
    
    // 实例化请求对象
    request.open("POST", "confirmation.asp");
    
    // 为 readystatechange 事件定义事件监听器
    request.onreadystatechange = function() {
        // 检查请求是否已完成并成功
        if(this.readyState === 4 && this.status === 200) {
            // 将来自服务器的响应插入 HTML 元素
            document.getElementById("result").innerHTML = this.responseText;
        }
    };
    
    // 检索表单数据
    var myForm = document.getElementById("myForm");
    var formData = new FormData(myForm);

    // 向服务器发送请求
    request.send(formData);
}
</script>
</head>
<body>
    <form id="myForm">
        <label>Name:</label>
        <div><input type="text" name="name"></div>
        <br>
        <label>Comment:</label>
        <div><textarea name="comment"></textarea></div>
        <p><button type="button" onclick="postComment()">Post Comment</button></p>
    </form>    
    <div id="result">
        <p>Content of the result DIV box will be replaced by the server response</p>
    </div>    
</body>
</html>

如果你没有使用 FormData 对象来发送表单数据,例如,如果你正在将表单数据以 query string 格式发送到服务器,即 request.send(key1=value1&key2=value2) 那么你需要使用 setRequestHeader() 方法向 方法显式设置请求标头 发送,如下所示:

request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

setRequestHeader() 方法,必须在调用 open() 之后调用 send() 之前调用。

一些常见的请求头是:application/x-www-form-urlencoded, multipart/form-data, application/json, application/xml, text/plain, text/html,等等。

注意: FormData 对象提供了一种简单的方法来构造一组表示表单字段及其值的键/值对,这些键/值对可以使用 XMLHttpRequest.send() 方法发送。 如果表单的编码类型设置为 multipart/form-data,则传输的数据与表单的 submit() 方法用于发送数据的格式相同。

这是我们的"confirmation.asp"文件的代码,它简单地输出用户提交的值。

示例

Download
<?php
if($_SERVER["REQUEST_METHOD"] == "POST") {
    $name = htmlspecialchars(trim($_POST["name"]));
    $comment = htmlspecialchars(trim($_POST["comment"]));
    
    // 检查表单字段值是否为空
    if(!empty($name) && !empty($comment)) {
        echo "<p>Hi, <b>$name</b>. Your comment has been received successfully.<p>";
        echo "<p>Here's the comment that you've entered: <b>$comment</b></p>";
    } else {
        echo "<p>Please fill all the fields in the form!</p>";
    }
} else {
    echo "<p>Something went wrong. Please try again.</p>";
}
?>

出于安全原因,浏览器不允许您进行跨域 Ajax 请求。 这意味着您只能从与原始页面相同的域向 URL 发出 Ajax 请求,例如,如果您的应用程序在域 "mysite.com" 上运行,则不能向 "othersite.com" 或任何其他域发出 Ajax 请求。 这通常称为同域策略

但是,您可以从任何域加载图像、样式表、JS 文件和其他资源。

提示:查看 jQuery Ajax 方法 以获得快速无缝的 Ajax 实施。 jQuery 框架提供了非常方便的方法来实现 Ajax 功能。

Advertisements