0
点赞
收藏
分享

微信扫一扫

异步通信技术AJAX | 原理剖析、发送Ajax请求四步

兵部尚输 2022-12-27 阅读 131

目录

一:快速搞定AJAX(第一篇)

1、传统请求及缺点

2、AJAX请求原理剖析

3、AJAX概述

4、XMLHttpRequest对象

5、AJAX GET请求

6、AJAX GET请求提交数据

7、AJAX GET请求的缓存问题

8、AJAX POST请求及模拟表单提交数据

9、经典案例:验证用户名是否可用

10、经典案例:显示学生列表  


一:快速搞定AJAX(第一篇)

1、传统请求及缺点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>演示传统请求,以及传统请求的缺点</title>
</head>
<body>

<!--1、直接在浏览器地址栏上输入URL-->
http://localhost:8080/ajax1/request

<!--2、超链接-->
<a href="/ajax1/request">传统请求(超链接)</a>

<!--3、form表单提交-->
<form action="/ajax1/request" method="get">
    <input type="submit" value="传统请求(form表单提交)">
</form>

<!--4、通过JS代码来发送请求-->
<input type="button" value="传统请求(通过JS代码发送请求)" onclick="sendRequest()">

<script type="text/javascript">
    function sendRequest(){
        // 发送请求
        document.location.href = "/ajax1/request"
    }
</script>

</body>
</html>

访问前的页面:

访问后的页面代码

2、AJAX请求原理剖析

3、AJAX概述

第一种方式:在按钮中使用onclick事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test JS</title>
</head>
<body>
    <script type="text/javascript">
        function sayHello() {
            alert("hello javascript1")
        }
    </script>

   <input type="button" value="hello1" onclick="sayHello()">

</body>
</html>

第二种方式:通过JS代码给按钮绑定事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test JS</title>
</head>
<body>
   <input type="button" value="hello2" id="helloBtn">

    <script type="text/javascript">
        // 这个function就是一个回调函数,当load事件发生之后,这个回调函数才会执行。
        // 页面加载完毕之后,load事件发生;给id="helloBtn"的元素绑定鼠标单击事件
        window.onload = function () {
            // 获取id="helloBtn"的对象
            var helloBtn = document.getElementById("helloBtn");
            // 给id="helloBtn"元素绑定click事件
            // 这个function也是一个回调函数;
            // 当helloBtn被click的时候,被鼠标单击的时候,这个回调函数会执行。
            helloBtn.onclick = function () {
                // this是发生事件的事件源对象。
                // 是按钮发生了鼠标单击,那么this代表的就是这个按钮对象。
                alert(this.value); // hello2
            }

        }
    </script>

</body>
</html>

4、XMLHttpRequest对象

var xhr = new XMLHttpRequest();
方法描述
abort()取消当前请求
getAllResponseHeaders()返回头部信息
getResponseHeader()返回特定的头部信息
open(method, url, async, user, psw

method:请求类型 GET 或 POST

url:文件位置

async:true(异步)或 false(同步)

user:可选的用户名称

psw:可选的密码

send() 将请求发送到服务器,用于 GET 请求
send(string)将请求发送到服务器,用于 POST 请求
setRequestHeader()向要发送的报头添加标签/值对
属性描述
onreadystatechange定义当 readyState 属性发生变化时被调用的函数
readyState保存 XMLHttpRequest 的状态。0:请求未初始化 1:服务器连接已建立 2:请求已收到 3:正在处理请求 4:请求已完成且响应已就绪
responseText以字符串返回响应数据
responseXML以 XML 数据返回响应数据
status返回请求的状态号200: "OK"   403: "Forbidden"    404: "Not Found"
statusText返回状态文本(比如 "OK" 或 "Not Found")

5、AJAX GET请求

(1)发送AJAX get请求,前端代码:

第一步:创建AJAX核心对象XMLHttpRequest

 var xhr = new XMLHttpRequest();

第二步:注册回调函数

        xhr.onreadystatechange == function () {
                    // ==4表示响应结束
                    if (xhr.readyState == 4) {
                        // 响应结束会有以一个状态码
                          if(this.status == 200){
                            // 正常结束,把接收服务器响应回来的内容放到div涂层中
                            document.getElementById("mydiv").innerHTML = this.responseText;
                        }  
                       }
                }

第三步:开启通道

xhr.open("GET", "/ajax/ajaxrequest1", true)

第四步:发送请求

 xhr.send()

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax get请求</title>
</head>
<body>
    <script type="text/javascript">
        window.onload = function () {
            document.getElementById("helloBtn").onclick = function () {
                // 第一步:创建AJAX核心对象XMLHttpRequest
                var xhr = new XMLHttpRequest();
                // 第二步:注册回调函数
                xhr.onreadystatechange = function () {
                    // console.log(xhr.readyState)
                    // 下面的xhr对象也可以换成this,代表当前按钮对象
                    // ==4表示响应结束
                    if (xhr.readyState == 4) {
                        // 响应结束会有以一个状态码
                        if (xhr.status == 404){
                            alert("对不起,您访问的资源不存在,请检查请求路径")
                        }else if(this.status == 500){
                            alert("对不起,服务器发生了严重的内部错误,请联系管理员")
                        }else if(this.status == 200){
                            // 正常结束
                            // 把接收服务器响应回来的内容放到div涂层中
                            document.getElementById("mydiv").innerHTML = this.responseText;
                        }
                    }
                }

                // 第三步:开启通道
                xhr.open("GET","/ajax/ajaxrequest1",true);
                // 第四步:发送请求
                xhr.send();

            }
        }

    </script>

    <!--给一个按钮,用户点击这个按钮的时候发送ajax请求-->
    <input type="button" value="ajax" id="helloBtn">
    <!--给一个div图层,ajax接收了响应的数据之后,在div中进行渲染-->
    <div id="mydiv"></div>
</body>
</html>

(2)发送AJAX get请求,后端代码:

package com.bjpowernode.javaweb.ajax;

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

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb.ajax
 * @Project:ajax
 * @name:AjaxRequest1Servlet
 * @Date:2022/12/5 17:25
 */
@WebServlet("/ajaxrequest1")
public class AjaxRequest1Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        out.print("<font color='red'>welcome to study ajax!!!!</font>");
    }
}

运行结果如下:

6、AJAX GET请求提交数据

第一种情况:直接写在路径后面,写死

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>get 请求发送数据</title>
</head>
<body>
<script type="text/javascript">
    window.onload = function () {
        document.getElementById("btn").onclick = function () {
            // 1、创建AJAX核心对象
            var xhr = new XMLHttpRequest();
            // 2、注册回调函数
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4){
                    if (xhr.status == 200) {
                        document.getElementById("myspan").innerText = this.responseText;
                    }else {
                        alert(xhr.status)
                    }
                }
            }

            ///3、开启通道
            xhr.open("GET","/ajax/ajaxrequest2?username=zhangsan&password=123");
            // 4、发送请求
            xhr.send();
        }
    }

</script>



    <input type="button" value="发送get请求" id="btn">
    <span id="myspan"></span>
</body>
</html>

后端代码:

package com.bjpowernode.javaweb.ajax;

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

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb.ajax
 * @Project:ajax
 * @name:AjaxRequest1Servlet
 * @Date:2022/12/5 17:25
 */
@WebServlet("/ajaxrequest2")
public class AjaxRequest2Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 设置响应的内容类型以及字符集
        response.setContentType("text/html;charset=UTF-8");
        // 获取响应流
        PrintWriter out = response.getWriter();
        // 获取ajax get请求提交的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        out.print("username="+username+",password="+password);

    }
}

第二种情况:写两个文本框,动态获取

前端代码进行修改:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>get 请求发送数据</title>
</head>
<body>
<script type="text/javascript">
    window.onload = function () {
        document.getElementById("btn").onclick = function () {
            // 1、创建AJAX核心对象
            var xhr = new XMLHttpRequest();
            // 2、注册回调函数
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4){
                    if (xhr.status == 200) {
                        document.getElementById("myspan").innerText = this.responseText;
                    }else {
                        alert(xhr.status)
                    }
                }
            }

            ///3、开启通道
            // 获取用户填写的username和password
            var username = document.getElementById("username").value;
            var password = document.getElementById("password").value;

            xhr.open("GET","/ajax/ajaxrequest2?username="+username+"&password="+password);
            // 4、发送请求
            xhr.send();
        }
    }

</script>

    <!--定义两个文本框-->
    username<input type="text" id="username"><br>
    password<input type="text" id="password"><br>

    <input type="button" value="发送get请求" id="btn">
    <span id="myspan"></span>
</body>
</html>

后端代码代码不变

7、AJAX GET请求的缓存问题

8、AJAX POST请求及模拟表单提交数据

(1)前端代码区别:

xhr.open("GET","/ajax/ajaxrequest2?username="+username+"&password="+password);

xhr.send();
xhr.open("POST","/ajax/ajaxrequest3",true);

// 设置请求头的内容类型。模拟form表单提交数据,在open之后,send之前。
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") 

// send函数中的参数就是发送的数据,这个数据在“请求体”当中发送。
xhr.send("username="+username+"&password="+password)

 (2)后端代码区别:

(3)模拟表单提交数据代码

①前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script type="text/javascript">
        window.onload = function () {
            document.getElementById("btn").onclick = function () {
                // 发送AJAX POST请求
                // 1. 创建AJAX核心对象
                var xhr = new XMLHttpRequest();
                // 2. 注册回调函数
                xhr.onreadystatechange = function () {
                    if (this.readyState == 4) {
                        if (this.status == 200) {
                            document.getElementById("mydiv").innerText = this.responseText;
                        }else{
                            alert(this.status);
                        }
                    }
                }
                // 3. 开启通道
                xhr.open("POST","/ajax/ajaxrequest3",true);
                // 怎么模拟AJAX提交form表单呢?设置请求头的内容类型(这行代码非常关键,是模拟form表单提交的关键代码。)
                // 设置请求头的内容类型时,必须在open之后。
                // xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
                xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
                // 4. 发送请求
                // 放到send()这个函数的小括号当中的数据,会自动在请求体当中提交数据。
                // 使用JS代码获取用户填写的用户名和密码
                var username = document.getElementById("username").value;
                var password = document.getElementById("password").value;
                xhr.send("username="+username+"&password="+password);

            }

        }
    </script>


    用户名<input type="text" id="username"><br>
    密码<input type="text" id="password"><br>
    <button id="btn">发送AJAX POST请求</button>

    <div  id="mydiv"></div>
</body>
</html>

②后端

package com.bjpowernode.javaweb.ajax;

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

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb.ajax
 * @Project:ajax
 * @name:AjaxRequest1Servlet
 * @Date:2022/12/5 17:25
 */
@WebServlet("/ajaxrequest3")
public class AjaxRequest3Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        // 获取提交数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        out.print("用户名是:" + username + ",密码是:" + password);
    }
}

9、经典案例:验证用户名是否可用

(1)创建数据库表,这里就是用前面学习Servlet创建的t_user表

 (2)前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script type="text/javascript">
        window.onload = function () {
            // 获取焦点,点进去清除提示
            document.getElementById("username").onfocus = function(){
                document.getElementById("myspan").innerHTML = " ";
            }


            // 失去焦点事件,显示提示
            document.getElementById("username").onblur = function () {
                // 发送AJAX POST请求
                // 1、创建核心对象
                var xhr = new XMLHttpRequest();
                // 2、注册回调函数
                xhr.onreadystatechange = function () {
                    if (this.readyState == 4) {
                        if (this.status == 200) {
                            document.getElementById("myspan").innerHTML = this.responseText;
                        } else {
                            alert(this.status);
                        }
                    }
                }
                // 3、开启通道
                xhr.open("POST","/ajax/ajaxrequest4",true)
                // 4、发送请求
                xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
                // 获取表单数据
                var username = document.getElementById("username").value;
                xhr.send("username="+username);
            }

        }
    </script>

    用户名:<input type="text" id="username">
    <span id="myspan"></span>
</body>
</html>

(3)后端代码

package com.bjpowernode.javaweb.ajax;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb.ajax
 * @Project:ajax
 * @name:AjaxRequest4Servlet
 * @Date:2022/12/6 14:29
 */
@WebServlet("/ajaxrequest4")
public class AjaxRequest4Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 响应到浏览器
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        // 打一个布尔标记
        boolean success = false;
        // 获取前端提交的数据
        String username = request.getParameter("username");
        // 连接数据库
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC", "root", "123");
            // 获取预编译的数据库操作对象
            String sql = "select id,username from t_user where username = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,username);
            // 执行sql
            rs = ps.executeQuery();
            // 处理查询结果集
            // 如果能查询到数据说明是存在的
            if (rs.next()) {
                success = true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        if (success) {
            // 用户名已存在,不可用
            out.print("<font color='red'>对不起,用户名已存在</font>");
        }else{
            // 用户名不存在,可以使用
            out.print("<font color='green'>用户名可以使用</font>");
        }
    }
}

(4)效果展示

10、经典案例:显示学生列表  

(1)创建数据库表,我们还是用上面的t_user表,把password当做学号看即可

(2)前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>发送AJAX请求,显示学生列表</title>
</head>
<body>
<script type="text/javascript">
    window.onload = function () {
            document.getElementById("btn").onclick = function () {
                // 1.创建核心对象
                var xhr = new XMLHttpRequest();
                // 2.注册回调函数
                xhr.onreadystatechange = function () {
                    if (this.readyState == 4) {
                        if (this.status == 200) {
                            document.getElementById("mybody").innerHTML = this.responseText
                        } else {
                            alert(this.status)
                        }
                    }
                }
                // 3.开启通道
                xhr.open("GET", "/ajax/ajaxrequest5", true)
                // 4.发送请求
                xhr.send()
            }
        }
</script>

    <input type="button" value="显示学员列表" id="btn">
    <table border="1px" width="50%">
        <tr>
            <th>序号</th>
            <th>姓名</th>
            <th>学号</th>
        </tr>
        <!--具体的内容需要连接数据库动态获取,为了便于操作,写一个tbody-->
        <tbody id="mybody">
            <!--具体内容响应在这里-->
        </tbody>

    </table>


</body>
</html>

(3)后端代码

package com.bjpowernode.javaweb.ajax;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb.ajax
 * @Project:ajax
 * @name:AjaxRequest5Servlet
 * @Date:2022/12/6 17:13
 */
@WebServlet("/ajaxrequest5")
public class AjaxRequest5Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 响应到浏览器
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        // 连接数据库
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC", "root", "123");
            // 获取预编译的数据库操作对象
            String sql = "select id,username,password from t_user ";
            ps = conn.prepareStatement(sql);
            // 执行sql
            rs = ps.executeQuery();
            // 处理查询结果集
            StringBuffer html = new StringBuffer(); // 使用拼串的方式
            while (rs.next()) {
                String id = rs.getString("id");
                String username = rs.getString("username");
                String password = rs.getString("password");
                // 拼串
                html.append("<tr>");
                html.append("<td>"+id+"</td>");
                html.append("<td>"+username+"</td>");
                html.append("<td>"+password+"</td>");
                html.append("</tr>");
            }
            // 输出写在外面,全部拼好串在输出
            out.print(html);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

(3)效果展示

①未点击按钮

② 点击按钮

 

举报

相关推荐

0 条评论