AJAX

AJAX

异步 JavaScript 和 XML(Asynchronous JavaScript and XML)

  • 2005 年,Google 通过 Google Suggest 使 AJAX 变得流行起来。

  • Google Suggest 使用 AJAX 创造出动态性极强的 web 界面:当您在谷歌的搜索框输入关键字时,JavaScript 会把这些字符发送到服务器,然后服务器会返回一个搜索建议的列表。

1.1、简介

1.1.1、什么是AJAX

  • AJAX 是一种用于创建快速动态网页的技术。
  • AJAX 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。**
    • 即可以在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容;
    • 传统的网页(不使用 AJAX)如果要更新内容,必须重新加载整个网页。
  • AJAX 不是新的编程语言,而是一种基于现有 Internet 标准的新方法。
    • XMLHttpRequest 对象:异步的与服务器交换数据;
    • JavaScript/DOM:信息显示/交互;
    • CSS:给数据定义样式;
    • JSON:作为转换数据的格式;
  • AJAX 与浏览器和平台无关。

1.1.2、工作原理

image-20210820231556288

1.2、iframe

使用前端的 iframe 标签来仿造 AJAX:页面局部刷新的效果。

HTML

  • 创建 iframe 和输入框;
  • 点击提交按钮,触发事件:获取输入框的值并赋值给 iframeURL
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>iframe局部刷新页面</title>
    <script type="text/javascript">
        function go() {
            let url = document.getElementById("url").value;
            document.getElementById("myIframe").src = url;
        }
    </script>
</head>
<body>
<div>
    <p>请输入地址:</p>
    <input id="url" type="text">
    <input type="button" value="提交" onclick="go()">
</div>
    
<div>
    <iframe id="myIframe" width="700px" height="500px"></iframe>
</div>
</body>
</html>

1.3、XMLHttpRequest

  • AJAX 的核心是 XMLHttpRequest 对象(XHR);
  • XHR 用于在后台与服务器交换数据:向服务器发送请求、解析服务器响应;
  • 原生 JS 实现 AJAX 比较麻烦,通常使用 jQuery 实现 AJAX

1.4、jQuery实现AJAX

jQuery 提供多个与 AJAX 有关的方法。

1.4.1、jQuery.ajax

jQuery 可以简写成 $,使用$.ajax(...)函数

部分参数

参数 类型 描述
async Boolean 是否异步请求,默认 true
beforeSend Function 发送请求前执行的函数(全局)
complete Function 请求完成后回调函数(成功或失败均调用)
contentType String 发送信息至服务器时的内容编码类型,
默认 application/x-www-form-urlencoded; charset=UTF-8
data String 发送到服务器的数据。
会自动转换为请求字符串格式
dataType String 指定服务器端返回的数据类型
xmlhtmlscriptjsonjsonptest
error Function 请求失败的回调函数(全局)
success Function 请求成功的回调函数(全局)
timeout Number 设置请求超时时间(毫秒)
type String 请求方式,GET(默认) 或 POST
url String 请求地址

通常来说,urldata 和回调函数是必要的。

1.4.2、环境搭建

搭建环境,测试 jQuery 实现 AJAX

配置

需要 web.xmlspringmvc 配置。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <filter>
        <filter-name>characterEncoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

applicationContext.xml

  • 过滤静态资源,否则 js 文件无法加载;
  • 处理 JSON 乱码。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
    <!-- 添加注解支持 -->
    <context:component-scan base-package="indi.jaywee.controller"/>
    <!-- 过滤静态资源 -->
    <mvc:default-servlet-handler/>
    <!-- 添加注解驱动 -->
        <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    <!-- 视图解析器 -->
    <bean id="internalResourceViewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
</beans>

JQuery库

要使用 jQuery 库,可以使用在线 CDN,也可以下载 JS 文件后导入项目。

引入在线 CDN

<script src="https://code.jquery.com/jquery-3.6.0.js"></script>

下载 JS 文件:jQuery 3.6.0开发版

  • 导入静态资源:位置web/statics/js/

  • 引入本地 JS 文件

    <script src="${pageContext.request.ContextPath}/statics/js/jquery-3.6.0.js"></script>
    

script 标签必须成对出现,不能自闭合!

1.4.3、测试

AjaxController

  • 使用 @RestController 注解,Controller 内的方法返回字符串(详见8、JSON);

  • 前端 AJAX 发送的数据(data)的键,必须与处理方法的参数名一致。

@RestController
public class AjaxController {

    /**
     * @param name     接收前端的data
     * @return 要响应的数据
     */
    @RequestMapping("/testName")
    public String testName(String name) {
        String msg = "admin";

        if (!msg.equals(name)) {
            msg = "user:" + name;
        }

        return msg;
    }

}

test.jsp

  • url:请求地址;
  • data:发送到服务器的数据
    • 以键值对的格式;
    • data 的键要与处理方法的参数名一致
  • success:请求成功的回调函数
    • 可以接收参数,参数是处理方法的返回值。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>AJAX测试</title>

    <script src="${pageContext.request.contextPath}/statics/js/jquery-3.6.0.js"></script>
    <script>
        function test() {
            $.ajax({
                url: "${pageContext.request.contextPath}/testName",
                data: {
                    "name": $("#username").val()
                },
                success: function (msg) {
                    console.log(msg)
                }
            })
        }
    </script>
</head>
<body>
<label>
    检测用户:<input type="text" id="username" onblur="test()">
</label>
</body>
</html>

流程

image-20210820204119417

  1. input 输入框:失去焦点,触发事件,调用 test() 函数;
  2. test() 函数
    • AJAX:发送请求到 Controller,携带 data 数据;
  3. Controller:接收请求,获取 data 参数, 处理逻辑并响应;
  4. success 回调函数:解析服务器响应,执行方法。

注意

  • 检查项目结构是否有 lib 目录;
  • 使用 @RestController 注解,Spring 自动将 Controller 内的方法返回字符串详见8、JSON):
    • 如果方法返回值类型是 String,直接返回字符串;
    • 如果方法返回值类型是对象或集合,返回 JSON 字符串;
    • 如果方法返回值是其它,根据一定规则返回字符串;
  • springmvc 配置文件
    • 是否有过滤静态资源;
    • 是否有处理 JSON 乱码;
  • 一切正常,但是请求无法发送:刷新 Mavenclean

1.5、应用

1.5.1、展示后台数据

以显示用户信息为例。

User

/**
 * ID
 */
private int id;
/**
 * 姓名
 */
private String name;
/**
 * 性别
 */
private String gender;

UserController

如果 RestController 中方法返回的是集合或对象,Spring 自动将其转换为 JSON 字符串

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/listUsers")
    public List<User> listUsers() {
        // 模拟用户列表
        List<User> userList = new ArrayList<>();

        userList.add(new User(1, "Jaywee", "男"));
        userList.add(new User(2, "小北", "女"));
        userList.add(new User(3, "SecretMrJ", "男"));
        userList.add(new User(4, "baby0", "女"));

        return userList;
    }
}

页面

  • 入口函数
    • 语法:windows.load = function(){...}$(function () {...})
    • JS 的优先级很高,会先运行 JS 函数再加载页面;
    • 入口函数的作用:等待页面加载完毕后才执行;
    • 必须将 JS 语句写在里面。否则 JS 函数会在页面加载之前执行,此时获取不到页面中的元素。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>展示用户</title>

    <script src="${pageContext.request.contextPath}/statics/js/jquery-3.6.0.js"></script>
    <script>
        $(function () {
            $("#btn").click(function () {
                $.ajax({
                    url: "${pageContext.request.contextPath}/user/listUsers",
                    success: function (userList) {
                        let htmlContent = "";

                        for (let i = 0; i < userList.length; i++) {
                            htmlContent += "<tr>" +
                                "<td>" + userList[i].id + "</td>" +
                                "<td>" + userList[i].name + "</td>" +
                                "<td>" + userList[i].gender + "</td>" +
                                "</tr>"
                        }

                        $("#content").html(htmlContent)
                    }
                })
            })
        })
    </script>

</head>
<body>

<input type="button" id="btn" value="加载">

<table>
    <thead>
    <tr>
        <td>ID</td>
        <td>姓名</td>
        <td>性别</td>
    </tr>
    </thead>
    <tbody id="content">
    </tbody>
</table>

</body>
</html>

流程

  1. btn 按钮绑定事件,等待触发;
  2. btn 按钮:点击按钮,触发事件;
    • 发送请求到 Controller
  3. Controller:接收请求, 处理逻辑并响应;
  4. success 回调函数:解析服务器响应,执行方法
    • 获取服务器返回的数据;
    • 循环拼接 htmlContent
    • htmlContent 赋值给 tbody

1.5.2、验证用户名

以注册时验证用户名是否可用为例。

UserController

@RestController
@RequestMapping("/user")
public class UserController {

    /**
     * @param username 用户名
     * @return 用户名可用返回ture, 否则返回false
     */
    @RequestMapping("/regist")
    public boolean regist(String username) {
        boolean flag = true;
        // 模拟数据库查询的用户名列表
        String[] nameList = new String[]{"admin", "jaywee", "小北"};
        // 判断用户名是否已存在
        for (String name : nameList) {
            if (name.equals(username)) {
                flag = false;
                break;
            }
        }
        return flag;
    }

}

页面

注意:使用.toString()将服务器返回的数据转换为字符串。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册</title>

    <script src="${pageContext.request.contextPath}/statics/js/jquery-3.6.0.js"></script>
    <script>
        $(function () {
            $("#username").blur(function () {
                $.ajax({
                    url: "${pageContext.request.contextPath}/user/regist",
                    data: {
                        "username": $("#username").val()
                    },
                    success(flag) {
                        console.log(flag);
                        console.log(flag.type);
                        if ('true' === flag.toString()) {
                            $("#verifyContent").html("用户名可用").css("color", "green");
                        } else {
                            $("#verifyContent").html("用户名已存在").css("color", "red");
                        }
                    }
                })
            })
        })
    </script>

</head>
<body>

<label>
    用户名:<input type="text" id="username">
</label>
<span id="verifyContent"></span>

</body>
</html>

流程

  1. input 输入框绑定事件,等待触发;
  2. input 输入框:失去焦点,触发事件;
    • 发送请求到 Controller,携带 data 参数;
  3. Controller:接收请求, 处理逻辑并响应;
  4. success 回调函数:解析服务器响应,执行方法
    • 获取服务器返回的数据,判断是 true 还是 false
    • 添加提醒字样。
posted @ 2021-08-20 23:29  Jaywee  阅读(107)  评论(0编辑  收藏  举报

👇