AJAX003——GET请求和POST请求

发布时间 2023-10-03 07:16:11作者: 猪无名

AJAX GET请求

普通代码

ajax1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax的get请求</title>
</head>
<body>
<!--用户点击按钮,发送ajax请求。-->
<input type="button" value="helloajax" id="helloBtn">

<!--ajax接收了响应的数据之后,在div中进行渲染。-->
<div id="mydiv">

</div>

<script type="text/javascript">
    window.onload = function () {
        document.getElementById("helloBtn").onclick = function () {
            //发送ajax get请求,一共四步

            //1.创建ajax对象
            var xhr = new XMLHttpRequest();
            //2.注册回调函数
            //这个回调函数在XMLHttpRequest对象的readyState属性改变的时候会自动调用。
            xhr.onreadystatechange = function () {
                //这个函数会被多次调用
                //0->1
                //1->2
                //2->3
                //3->4

                //XMLHttpRequest对象的readyState属性等于4的时候,表示响应结束
                if(this.readyState == 4){
                    //响应结束之后,会有一个HTTP状态码:200表示成功,404表示资源找不到,500表示服务器内部错误。
                    // console.log("响应结束。")
                    if(this.status==404){
                        alert("资源找不到")
                    }else if(this.status==500){
                        alert("服务器内部出现严重错误,请联系管理员。")
                    }else if(this.status==200){
                        // alert("请求成功")
                        //通过XMLHttpRequest对象的responseText属性可以获得服务器的响应数据。
                        // alert(this.responseText);
                        //把获取到的信息放到div图层当中。
                        document.getElementById("mydiv").innerHTML = this.responseText;
                    }
                }
            }
            //3.开启通道(open只是打开通道,和服务器建立连接,并没有发送请求。)
            xhr.open("get","/ajax001/ajaxservlet001",true);
            //4.发送请求
            xhr.send();
        }
    }
</script>
</body>
</html>

ajaxservlet001.java

package com.zwm.ajax.web;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/ajaxservlet001")
public class ajaxservlet001 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //服务器的代码和原来的一样。
        //只是out响应的时候,浏览器客户端的XMLHttpRequest对象会接受到响应的信息。
        PrintWriter out = response.getWriter();
        out.print("hello,AJAX.");

    }
}

提交数据代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="提交用户名和密码" id="btn">

<script type="text/javascript">
  window.onload = function () {
    document.getElementById("btn").onclick = function () {
      var xmlHttpRequest = new XMLHttpRequest();
      xmlHttpRequest.open("GET","/ajax001/ajaxservlet005?username=zwm&userage=23",true);
      xmlHttpRequest.send();
      xmlHttpRequest.onreadystatechange = function () {
        if (xmlHttpRequest.readyState === 4) {
          if (xmlHttpRequest.status === 200) {
           alert(xmlHttpRequest.responseText)
          }
        }
      }
    }
  }
</script>

</body>
</html>
package com.zwm.ajax.web;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/ajaxservlet005")
public class ajaxservlet005 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String username = request.getParameter("username");
        String userage = request.getParameter("userage");

        response.setContentType("text/xml;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("姓名:"+username+"年龄:"+userage);

    }
}

GET请求的缓存问题

  • 对于低版本的IE浏览器来说,AJAX的get请求可能会走缓存。存在缓存问题。对于现代的浏览器来说,大部分浏览器都已经不存在AJAX get缓存问题了。
  • 什么是AJAX GET请求缓存问题呢?
    • 在HTTP协议中是这样规定get请求的:get请求会被缓存起来。
    • 发送AJAX GET请求时,在同一个浏览器上,前后发送的AJAX请求路径一样的话,对于低版本的IE来说,第二次的AJAX GET请求会走缓存,不走服务器。
  • POST请求在HTTP协议中规定的是:POST请求不会被浏览器缓存。
  • GET请求缓存的优缺点:
    • 优点:直接从浏览器缓存中获取资源,不需要从服务器上重新加载资源,速度较快,用户体验好。
    • 缺点:无法实时获取最新的服务器资源。
  • 浏览器什么时候会走缓存?
    • 第一:是一个GET请求
    • 第二:请求路径已经被浏览器缓存过了。第二次发送请求的时候,这个路径没有变化,会走浏览器缓存。
  • 如果是低版本的IE浏览器,怎么解决AJAX GET请求的缓存问题呢?
    • 可以在请求路径url后面添加一个时间戳,这个时间戳是随时变化的。所以每一次发送的请求路径都是不一样的,这样就不会走浏览器的缓存问题了。
    • 可以采用时间戳:“url?t=” + new Date().getTime()
    • 或者可以通过随机数:“url?t=” + Math.random()
    • 也可以随机数+时间戳…

AJAX POST请求

  • AJAX POST请求和GET请求的代码区别在哪里?就是前端代码有区别。后端代码没有区别。

    //这行代码用于设置请求头的 Content-Type,指定请求的数据类型为表单形式(application/x-www-form-urlencoded)。
    //这行代码应该放在 open() 方法之后、send() 方法之前。模拟form表单提交数据。
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") 
    // 获取表单中的数据
    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;
    // send函数中的参数就是发送的数据,这个数据在“请求体”当中发送。
    xhr.send("username="+username+"&password="+password)
    

案例一

  • 实现一个案例:使用AJAX POST请求实现用户注册的时候,用户名是否可用。(验证用户名是否可以注册)实现步骤如下:

    • 在前端,用户输入用户名之后,失去焦点事件blur发生,然后发送AJAX POST请求,提交用户名
    • 在后端,接收到用户名,连接数据库,根据用户名去表中搜索
    • 如果用户名已存在
      • 后端响应消息:对不起,用户名已存在(在前端页面以红色字体展示)
    • 如果用户名不存在
      • 后端响应消息:用户名可以使用(在前端页面以绿色字体展示)

    具体代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户名验证</title>
    </head>
    <body>
    用户名:<input type="text" id="text-username">
    <span id="span-response"></span>
    
    <script type="text/javascript">
      window.onload = function () {
        document.getElementById("text-username").onblur = function () {
          var xmlHttpRequest = new XMLHttpRequest();
          xmlHttpRequest.onreadystatechange = function () {
            if(xmlHttpRequest.readyState == 4){
              if(xmlHttpRequest.status == 200){
                  document.getElementById("span-response").innerHTML = xmlHttpRequest.response;
              }else{
                alert(xmlHttpRequest.status)
              }
            }
          }
          xmlHttpRequest.open("POST","/ajax001/ajaxservlet006",true);
          //这行代码用于设置请求头的 Content-Type,指定请求的数据类型为表单形式(application/x-www-form-urlencoded)。
          //这行代码应该放在 open() 方法之后、send() 方法之前。
          xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
          var username = document.getElementById("text-username").value;
          xmlHttpRequest.send("username="+username);
        }
      }
    </script>
    
    </body>
    </html>
    
  package com.zwm.ajax.web;
  
  import com.zwm.ajax.utils.DBUtil;
  import jakarta.servlet.ServletException;
  import jakarta.servlet.annotation.WebServlet;
  import jakarta.servlet.http.HttpServlet;
  import jakarta.servlet.http.HttpServletRequest;
  import jakarta.servlet.http.HttpServletResponse;
  
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  
  @WebServlet("/ajaxservlet006")
  public class ajaxservlet006 extends HttpServlet {
      @Override
      protected void doPost(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
  
          response.setContentType("text/xml;charset=utf-8");
          PrintWriter out = response.getWriter();
  
          String username = request.getParameter("username");
  
          Connection connection = null;
          PreparedStatement  preparedStatement = null;
          ResultSet resultSet = null;
  
          try {
              connection = DBUtil.getConnection();
              String sql = "select * from t_user where username = ?";
              preparedStatement = connection.prepareStatement(sql);
              preparedStatement.setString(1, username);
              resultSet = preparedStatement.executeQuery();
              if (resultSet.next()) {
                  out.write("<font color='red'>用户名已存在</font>");
              }else {
                  out.write("<font color='green'>用户名可用</font>");
              }
          } catch (Exception e) {
              e.printStackTrace();
          }finally {
              DBUtil.close(connection,preparedStatement,resultSet);
          }
      }
  }
  package com.zwm.ajax.utils;
  
  import java.sql.*;
  import java.util.ResourceBundle;
  
  /**
   * @author 猪无名
   * @date 2023/8/14 12 26
   * discription:JDBC工具类
   * @version 1.0
   * @since  1.0
   */
  public class DBUtil {
      private static final ResourceBundle bundle = ResourceBundle.getBundle("resources/jdbc");
      private static String driver = bundle.getString("driver");
      private static String url = bundle.getString("url");
      private static String user = bundle.getString("user");
      private static String password = bundle.getString("password");
  
      //不让创建对象,因为工具类中的方法都是静态的,不需要创建对象。
      //为了防止创建对象,将构造方法私有化。
      private DBUtil(){}
  
      //类加载时,注册驱动。
      static {
          try {
              Class.forName(driver);
          } catch (ClassNotFoundException e) {
             e.printStackTrace();
          }
      }
  
      private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
      /**这里没有使用数据库连接池,直接创建连接对象。
       * @return 连接对象
       * @throws SQLException
       */
      public static Connection getConnection() throws SQLException {
          Connection connection = threadLocal.get();
          if(connection == null){
              connection = DriverManager.getConnection(url, user, password);
              threadLocal.set(connection);
          }
          return connection;
      }
  
      /**
       * 关闭资源
       * @param connection 连接对象
       * @param statement  执行对象
       * @param resultSet   结果集
       */
      public static void close(Connection connection, Statement statement, ResultSet resultSet) {
          if (resultSet != null) {
              try {
                  resultSet.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
          if (statement != null) {
              try {
                  statement.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
          if (connection != null) {
              try {
                  connection.close();
                  //Tomcat服务器是支持线程池的,线程池的线程是复用的,所以需要把连接对象从线程池中移除。
                  threadLocal.remove();
              } catch (SQLException e) {
                  throw new RuntimeException(e);
              }
          }
      }
  }
  driver=com.mysql.cj.jdbc.Driver
  url=jdbc:mysql://localhost:3306/mvc
  user=root
  password=root

案例二

  • 实现一个案例:用户点击按钮之后,发送AJAX请求,显示学生列表。

    • 在后端java程序中拼接HTML代码,然后将HTML代码直接响应到浏览器客户端。这种方式不好,不应该在java代码中编写HTML代码,能否在java程序中直接向前端响应数据?可以,可以在后端拼接JSON格式的字符串,或者XML格式的字符串,将这个字符串发送给前端,前端解析即可。

具体代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="显示学员列表" id="btn">
<table border="1" width="50%">
    <thead>
    <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>住址</th>
    </tr>
    </thead>
    <tbody id="stutbody">
    </tbody>
</table>
<script type="text/javascript">
    window.onload = function () {
        document.getElementById("btn").onclick = function () {
            var xhr = new XMLHttpRequest();
            xhr.open("get", "/ajax001/ajaxservlet007", true);
            xhr.send();
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4){
                    if(xhr.status == 200){
                    document.getElementById("stutbody").innerHTML = xhr.responseText;
                    }else {
                        alert(xhr.status);
                    }
                }
            }
        }
    }
</script>
</body>
</html>
package com.zwm.ajax.web;

import com.zwm.ajax.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

@WebServlet("/ajaxservlet007")
public class ajaxservlet007 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/xml;charset=utf-8");
        PrintWriter out = response.getWriter();

        Connection connection = null;
        PreparedStatement  preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = DBUtil.getConnection();
            String sql = "select * from stu";
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            String text = "";
            while (resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("username");
                int age = resultSet.getInt("age");
                String address = resultSet.getString("address");
                text += "<tr><td>"+id+"</td><td>"+name+"</td><td>"+age+"</td><td>"+address+"</td></tr>";
            }
            out.print(text);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,preparedStatement,resultSet);
        }
    }
}

存在的缺点:

在后端进行前端代码的拼接,这样很不好维护,是否可以只返回数据,让前端处理格式?

可以 ,需要借助JSON或者XML。