使用 JavaScript 实现 AJAX

151 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

XMLHttpRequest

XMLHttpRequest 对象的常用方法

open(methodName, URL, isAsync);

该方法主要用于与服务器连接建立。其中参数的意义如下所示:

  • methodName 指定请求的方法名。
  • URL 指定请求地址。
  • isAsync 是一个 boolean 值,代表是否采用异步方式(默认 true;若无特殊需求,此值一般都填 true)。
send(content);

发送 HTTP 请求。其中参数的意义如下所示:

  • content 是可选项,用来指定请求参数,将请求参数作为请求体的一部分一起发送给服务器。通常只在 post 方式下才使用 content 参数(get 请求方式不携带请求体)。
setRequestHeader(header, value);

在 HTTP 请求头中设置 key/value 对。在 HTTP 请求头中设置 key/value 对时,若为 get 请求方式则不用设置。

若为 post 方式,则当请求中包含文件上传元素时,设置为以下内容:

XMLHttpRequest.setRequestHeader("Content-Type", "mulipart/form-data")` ;

而当请求中不包含文件上传元素时,设置为以下内容:

`XMLHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")`;

XMLHttpRequest 对象的常用属性

readystate

readystate 表示 XMLHttpRequest 对象发送的 HTTP 请求状态,共有五种,如表所示。

状 态 值简 介
0表示 XMLHttpRequest 对象没有初始化。
1表示 XMLHttpRequest 对象开始发送请求:已经执行了 open() 方法并完成了相关资源的准备。
2表示 XMLHttpRequest 对象已将请求发送完毕:已经执行了 send() 方法来发送请求,但是还没有收到响应。
3表示 XMLHttpRequest 对象开始读取响应信息:已经接收到 HTTP 响应的头部信息,但是还没有将响应体接收完毕。
4表示 XMLHttpRequest 对象将响应信息全部读取完毕。

status

status 表示 HTTP 响应中的状态码,各状态码的含义如表所示。

状 态 码含 义
200服务器正常响应。
400无法找到请求的资源。
403没有访问权限。
404访问的资源不存在。
500服务器内部错误,很可能是服务器代码有错。

可以发现,只有当状态码为 200 时才表示响应成功;否则,说明 HTTP 响应不正常。

onreadystatechange

指定 XMLHttpRequest 对象的回调函数。每当 readyState 的属性值改变时,此回调函数就会被调用一次。

responseText

从服务器端返回的字符串格式的响应内容。

responseXML

从服务器端返回的 XML 格式的数据,可以直接被当成 DOM 对象使用。

POST 请求

使用 JavaScript 实现 AJAX,有 post 或 get 两种请求方式,大体的步骤都相同,如下。

  • 创建 XMLHttpRequest 对象,即创建一个异步调用对象。
  • 设置并编写回调函数。
  • 初始化 XMLHttpRequest 对象的参数值(若是 post 方式,还需要设置“请求头”)。
  • 发送 HTTP 请求。
  • 在回调函数中编写获取异步调用返回的数据。
  • 使用 JavaScript 或 jQuery 等实现局部刷新。

创建项目

image.png

打开 ServletAjaxProject 文件夹下方的 pom.xml 在文件中添加下方依赖。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.yamiya</groupId>
  <artifactId>ServletAjaxProject</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>ServletAjaxProject Maven Webapp</name>
  <url>http://maven.apache.org</url>
    <dependencies>
    <!-- servlet3.x 依赖 jar 包 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- jsp 依赖 jar 包 -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>
  </dependencies>
    <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <configuration>
                        <!-- 端口 -->
                        <port>8080</port>
                        <!-- 编码-->
                        <uriEncoding>UTF-8</uriEncoding>
                        <!-- 项目的启动路径-->
                        <path>/</path>
                            <!-- 项目名称 -->
                        <finalName>ServletAjaxProject </finalName>
                        <!-- 启动的命令名称-->
                        <server>tomcat7</server>
                    </configuration>
                </plugin>
            </plugins>
    </build>
</project>

准备接口,接口功能是校验手机号是否绑定,在 src/main/java/org/yamiya/servlet 目录下建一个名为 MobileServlet.java 的 Servlet,程序如下:

package org.yamiya.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/MobileServlet")
public class MobileServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置发送到客户端响应的内容类型
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String mobile = request.getParameter("mobile");
        // 假设已经存在号码为 18888888888 的电话
        if ("18888888888".equals(mobile)) {
            out.print("true"); // 注意,参数值是字符串类型
        } else {
            out.print("false"); // 注意,参数值是字符串类型
        }
        out.close();
    }
}

现在用 post 方法,来实现“检测手机号码是否已绑定”的功能。在项目 src/main/webapp 下创建 index_post.jsp 中添加客户端代码。

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="">
        <input type="text" id="mobile"/>
        <font color="red" id="tip"></font>
        <br/>
        <input type="button" value="绑定" onclick="isExist()"/>
    </form>
</body>
    <script type="text/javascript">
        function isExist() {
          var $tip = document.getElementById("tip");
            var $mobile =document.getElementById("mobile").value;
            if ($mobile == null || $mobile.length != 11) {
                $tip.innerHTML="请输入正确的手机号码!";
            } else{
                // 1.创建 XMLHttpRequest 对象
                // (注意:xmlHttpRequest 前没有 var,所以是一个全局变量)
                xmlHttpRequest = new XMLHttpRequest();
                // 2.设置回调函数(注意:回调函数的名字后面没有小括号“()”)
                xmlHttpRequest.onreadystatechange = callBack;
                // 3.初始化 XMLHttpRequest 对象的参数值及请求头
                var url = "MobileServlet";
                xmlHttpRequest.open("post", url, true);
                // 4.POST 方式需要设置“请求头”
                xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                // 5.发送 HTTP 请求
                var data = "mobile=" + $mobile;
                xmlHttpRequest.send(data);
            }
        }
        // AJAX 回调函数
        function callBack() {
            if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
                var $tip = document.getElementById("tip");
                // 获取异步调用返回的数据
                var data = xmlHttpRequest.responseText;
                // 使用 JavaScript 或 jQuery 等实现局部刷新
                if (data.trim()== "true") {
                    $tip.innerHTML="此号码已经被绑定,请尝试其他号码!";
                } else {
                    $tip.innerHTML="绑定成功!";
                }
            }
        }
    </script>
</html>

get请求

创建项目,和上一个一样的

pom也是

在 ServletAjaxProject 在项目的 src/main/webapp 下创建 index_get.jsp 客户端代码如下。

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="">
        <input type="text" id="mobile"/>
        <font color="red" id="tip"></font>
        <br/>
        <input type="button" value="绑定" onclick="isExist()"/>
    </form>
</body>
    <script type="text/javascript">

        function isExist() {
            var $tip = document.getElementById("tip");
            var $mobile =document.getElementById("mobile").value;
            if ($mobile == null || $mobile.length != 11) {
                $tip.innerHTML="请输入正确的手机号码!";
            } else{
            // 1.创建 XMLHttpRequest 对象
                //(注意:xmlHttpRequest 前没有 var,所以是一个全局变量)
                xmlHttpRequest = new XMLHttpRequest();
                // 2.设置回调函数(注意:回调函数的名字后面没有小括号“()”)
                xmlHttpRequest.onreadystatechange = callBack;
                // 3.初始化 XMLHttpRequest 对象的参数值
                var url = "MobileServlet";
                var data = "mobile=" + $mobile;
                xmlHttpRequest.open("get", url+"?"+data, true);
                // 4.发送 HTTP 请求
                xmlHttpRequest.send(data);
            }
        }
        // AJAX 回调函数
        function callBack() {
            if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
                var $tip = document.getElementById("tip");
                // 获取异步调用返回的数据
                var data = xmlHttpRequest.responseText;
                // 使用 JavaScript 或 jQuery 等实现局部刷新
                if (data.trim()== "true") {
                    $tip.innerHTML="此号码已经被绑定,请尝试其他号码!";
                } else {
                    $tip.innerHTML="绑定成功!";
                }
            }
        }
    </script>
</html>

总结: 通过对比可以发现,get 方式和 post 方式的不同之处如下:

  • 将XMLHttpRequest对象的open()方法中的method参数值改为get。
  • 给XMLHttpRequest对象的send()方法中的url参数,加上需要传递的参数值(把url的值,从“请求地址”改为“请求地址?参数名1=参数值1&参数名2=参数值2&...”)。
  • 删除设置XMLHttpRequest对象头信息的代码。
  • 将XMLHttpRequest对象的send(data)方法中的data,改为null(将data的值,转移到了send()方法的url参数中)。

可见,将post方式改为get方式后,把需要发送的参数从send()方法转移到open方法中的url参数中,并且不需要再设置头信息。