AJAX-老杜

Ajax(Asynchronous Javascript And Xml)

  • 传统请求的缺点:

    • 发送一个请求就会前空掉原界面所有的内容
    • Ajax实现局部刷新
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SSJMyRBF-1689150304234)(C:\Users\26332\AppData\Roaming\Typora\typora-user-images\image-20230709103508924.png)]

  • 什么是异步,什么是同步?

    • 异步:假设有他t1和t2线程,t1和t2线程并发
    • 同步:假设有他t1和t2线程,t2在执行的时候,必须等待t2线程执行到某个位置
    • Ajax是异步请求:在同一个浏览器页面,可以发送多个Ajax请求,这些Ajax请求之间不需要等待

XMLHttpRequest对象

链接:https://blog.youkuaiyun.com/jsdoulaoula/article/details/125889583


Ajax GET请求

发送Ajax get请求,前端jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Ajax</title>
  </head>
  <body>
  <script type="text/javascript ">
    //页面加载完成后调方法
    window.οnlοad=function () {
      document.getElementById("btn").onclick = function () {
        //1.创建XMLHttpRequest对象
        var xhr = new XMLHttpRequest();
        //第二步:注册回调函数
        //这是一个回调函数,这个函数在XMLHttpRequest对象的readyState状态值发生改变时被调用
        xhr.onreadystatechange = function () {
          //这里回调函数会被调用多次
          //0->1被调用一次
          //1->2被调用一次
          //2->3被调用一次
          //3->4被调用一次
          // console.log(xhr.readyState);
          //当XMLHttpRequest对象的状态是4的时候,表示响应结束
          //readyState是XMLHttpRequest 的状态。0:请求未初始化 1:服务器连接已建立 2:请求已收到 3:正在处理请求 4:请求已完成且响应已就绪
          if (xhr.readyState == 4) {
            //status是浏览器响应的状态码。200:成功  400:找不到资源  500:服务器错误
            if (xhr.status == 200) {
              //取到要改变的元素
              var text= document.getElementById("textid")
              //responseText是将servlet的输出打到这里
              text.value=xhr.responseText;
            }
          }
        }
        //第三步:开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求)
        // open(method: string, url: string): void;
        // open(method: string, url: string, async: boolean, username?: string | null, password?: string | null): void;
        //method:请求方法,url:请求地址,async:是否异步,username,password
        xhr.open("GET","/ajax2/ajaxtese",true)
        //发送请求
        xhr.send();
      }
    }
  </script>
  <input type="button" value="点击我" id="btn">
<%--  <span id="textid"></span>--%>
  <input type="text" id="textid">
  </body>
</html>

前端代码模板:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Ajax</title>
</head>
<body>
<script type="text/javascript ">
    //页面加载完成后调方法
    window.οnlοad=function () {
        //1.创建XMLHttpRequest对象
        var xhr = new XMLHttpRequest();
        document.getElementById("btn").onclick = function () {
            //2.注册回调函数
            //这是一个回调函数,这个函数在XMLHttpRequest对象的readyState状态值发生改变时被调用
            //在回调函数后设置textChangeFunction方法
            xhr.onreadystatechange = textChangeFunction
            //3.开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求)
            //method:请求方法,url:请求地址,async:是否异步,username,password
            xhr.open("GET","/ajax2/ajaxtese",true)
            //4.发送请求
            xhr.send();
        }
        //创建textChangeFunction方法
        function textChangeFunction(){
            //readyState是XMLHttpRequest 的状态。0:请求未初始化 1:服务器连接已建立 2:请求已收到 3:正在处理请求 4:请求已完成且响应已就绪
            if (xhr.readyState == 4) {
                //status是浏览器响应的状态码。200:成功  400:找不到资源  500:服务器错误
                if (xhr.status == 200) {
                    //取到要改变的元素
                    var text= document.getElementById("textid")
                    //responseText是将servlet的输出打到这里
                    text.value=xhr.responseText;
                }
            }
        }
    }
</script>
<input type="button" value="点击我" id="btn">
<%--  <span id="textid"></span>--%>
<input type="text" id="textid">
</body>
</html>

后端Servlet代码:

package servlet;

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("/ajaxtese")
public class ajaxservlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.print("看text里有值了");
    }
}
  • 怎么Ajax get请求如何提交数据呢?

    • get请求提交数据是在“请求行”上提交,格式是url?属性名=属性值&属性名=属性值…

    • 就在第三步的开启通道前获取数据对象,再开启通道是填写的路径将该数据对象按格式绑定上去

    • 前端代码:

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
        <head>
          <title>Ajax</title>
        </head>
        <body>
        <script type="text/javascript ">
          //页面加载完成后调方法
          window.οnlοad=function () {
            document.getElementById("btn").onclick = function () {
              //1.创建XMLHttpRequest对象
              var xhr = new XMLHttpRequest();
              //第二步:注册回调函数
              //这是一个回调函数,这个函数在XMLHttpRequest对象的readyState状态值发生改变时被调用
              xhr.onreadystatechange = function () {
                //这里回调函数会被调用多次
                //0->1被调用一次
                //1->2被调用一次
                //2->3被调用一次
                //3->4被调用一次
                // console.log(xhr.readyState);
                //当XMLHttpRequest对象的状态是4的时候,表示响应结束
                //readyState是XMLHttpRequest 的状态。0:请求未初始化 1:服务器连接已建立 2:请求已收到 3:正在处理请求 4:请求已完成且响应已就绪
                if (xhr.readyState == 4) {
                  //status是浏览器响应的状态码。200:成功  400:找不到资源  500:服务器错误
                  if (xhr.status == 200) {
                    //取到要改变的元素
                    document.getElementById("spanid").innerHTML=xhr.responseText;
                    //responseText是将servlet的输出打到这里
                  }
                }
              }
              //第三步:开启通道(open只是浏览器和服务器建立连接,通道打开,并不会发送请求)
              // open(method: string, url: string): void;
              // open(method: string, url: string, async: boolean, username?: string | null, password?: string | null): void;
              //method:请求方法,url:请求地址,async:是否异步,username,password
              var username = document.getElementById("username").value;
              var password = document.getElementById("password").value;
              xhr.open("GET","/ajax2/ajaxtese?username="+username+"&password="+password,true)
              //发送请求
              xhr.send();
            }
          }
        </script>
        <input type="text" id="username"><br>
        <input type="password" id="password"><br>
        <input type="button" value="登录" id="btn"><br>
        <span id="spanid"></span><br>
        </body>
      </html>
      
      

      后端代码:

      package servlet;
      
      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("/ajaxtese")
      public class ajaxservlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              PrintWriter out = response.getWriter();
              String username = request.getParameter("username");
              String password = request.getParameter("password");
      
              out.print("账号:"+username+",密码:"+password+"<br>登陆成功");
          }
      }
      

Ajax GET请求的缓存问题

  • 对于低版本的IE浏览器,Ajax的get请求可能会走缓存,存在缓存问题

  • 对于现在的浏览器来说,大部分浏览器都不存在该问题

  • 什么是Ajax get请求的缓存问题呢?

    • 在HTTP协议中是这样规定get请求的:get请求会被缓存起来
    • 在HTTP协议中是这样规定post请求的:post请求会被缓存起来
  • GET请求缓存的优缺点:

    • 直接从浏览器缓存中获取资源,不需要从服务器上重新加载资源,速度较快,用户体验好。
    • 缺点:无法实时获取到服务器的资源
  • 什么时候会走缓存?

    • 第一:是一个GET请求
    • 第二:请求路径已经被浏览器缓存过了,第二人发送路径和缓存一模一样
  • 如果是低版本的IE浏览器,怎么解决Ajax GET请求的缓存问题呢?

    • 在url加一个时间戳,这样每次请求的url都不一样

    • usr?time=new Date().getTime()
      

Ajax POST请求

  • 要注意:若想使用POST请求提交form表单数据,则需要注意两点(与GET请求不同点)

    • 1.要在打开通道前设置请求头内容类型

      xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
      
    • 2.要将绑定的数据放到发送请求处

      //放到send()这个函数的小括号当中的数据,会自动在前驱图当中提交数据
      var username=document.getElementById("usernameid").value;
      var password=document.getElementById("passwordid").value;
      xhr.send("username="+username+"&password="+password);
      
  • 全部代码:(后端Java代码不变)

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>发送Ajax POST请求</title>
      </head>
      <body>
        <script type="text/javascript">
          window.οnlοad=function (){
            document.getElementById("btnid").οnclick=function (){
              //创建XMLHttpRequest对象
              var xhr = new XMLHttpRequest();
              //注册回调函数
              xhr.onreadystatechange=function (){
                if (xhr.readyState==4){
                  if (xhr.status==200){
                      document.getElementById("spanid").innerHTML=xhr.responseText;
                  }
                }
              }
              //开启通道
              xhr.open("POST","/ajax/ajaxtext",true);
              //发送请求
              //怎么模拟Ajax提交form表单呢?设置请求头内容类型,必须在open之后
              xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
              //放到sen()这个函数的小括号当中的数据,会自动在前驱图当中提交数据
              var username=document.getElementById("usernameid").value;
              var password=document.getElementById("passwordid").value;
              xhr.send("username="+username+"&password="+password);
            }
          }
        </script>
        username:<input type="text" id="usernameid"><br>
        password:<input type="password" id="passwordid"><br>
        <input type="button" value="登录" id="btnid"><br>
        <span id="spanid"> </span>
      </body>
    </html>
    
    

AJAX经典案例-验证用户名是否可用

  • 实现一个案例:使用Ajax POST请求实现用户注册的时候,用户名是否可用

    • 实现步骤:

      • 在前端,用户输入用户名之后,失去焦点事件blur发生,然后发送Ajax POST请求,提交用户名
      • 在后端,接收到用户名,连接数据库,根据用户名在表中搜索
      • 如果用户名存在
        • 后端响应信息:对不起,用户名已存在(在前端页面以红色字体展示)
      • 如果用户名不存在
        • 后端响应信息:用户名可使用(在前端以绿色字体展示)
    • //前端代码
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
        <head>
          <title>用户注册</title>
        </head>
        <body>
      
        <script type="text/javascript" charset="UTF-8">
          window.οnlοad=function (){
            //将username框失去焦点事件绑定方法
            document.getElementById("usernameid").οnblur=function (){
              //创建XMLHttpRequest
              var xhr = new XMLHttpRequest;
              //注册回调函数
              xhr.onreadystatechange=function (){
                //如果请求状态结束则进入
                if (xhr.readyState==4){
                  //如果浏览器请求成功
                  if (xhr.status==200){
                    document.getElementById("spanid").innerHTML=xhr.responseText;
                  }
                }
              }
              //开启通道
              xhr.open("POST","/userOrder/usernameTest",true);
              //设置请求头内容类型
              xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
              //绑定数据发送到后端
              var username = document.getElementById("usernameid").value;
              xhr.send("username="+username)
            }
          }
        </script>
          useranme:<input type="text" id="usernameid"><span id="spanid"></span> <br>
          password:<input type="password" id="passwordid"><br>
          <input type="submit" value="登录"><br>
        </body>
      </html>
      
      //后端代码
      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.*;
      
      @WebServlet("/usernameTest")
      public class testUsername extends HttpServlet {
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              PrintWriter out = response.getWriter();
              response.setContentType("text/html");
              //获取前端传来的用户名
              String username = request.getParameter("username");
              Connection conn=null;
              PreparedStatement ps=null;
              ResultSet rs=null;
              //注册驱动
              try {
                  Class.forName("com.mysql.cj.jdbc.Driver");
              //创建连接
                  conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/mvc","root","123456");
                  String sql="select * from user where username=?";
                  ps=conn.prepareStatement(sql);
                  ps.setString(1,username);
                  rs=ps.executeQuery();
                  if (rs.next()){
                      out.print("<font size=\"2px\" color=\"red\">用户名重复</font>");
                  }else {
                      out.print("<font size=\"2px\" color=\"green\">用户名合法</font>");
                  }
              } catch (ClassNotFoundException e) {
                  e.printStackTrace();
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
              }finally {
                  if (conn!=null){
                      try {
                          conn.close();
                      } catch (SQLException throwables) {
                          throwables.printStackTrace();
                      }
                  }
                  if (ps!=null){
                      try {
                          ps.close();
                      } catch (SQLException throwables) {
                          throwables.printStackTrace();
                      }
                  }
                  if (rs!=null){
                      try {
                          rs.close();
                      } catch (SQLException throwables) {
                          throwables.printStackTrace();
                      }
                  }
              }
          }
      }
      

基于JSON的数据交换

  • 在WEB前端中,如何将一个json格式的字符串转换成json对象(外层的双引号和里面的双引号冲突了,所以加个\来进行转译)

    • var jsonStr = "{\"username\" : \"zhangsan\", \"password\" : \"1233344\"}"
      var jsonObj = JSON.parse(jsonStr)
      console.log(jsonObj.username)
      console.log(jsonObj.password)
      
      
  • 在后端拼接JSON格式的字符串,响应给前端的浏览器

    • json.append("[");
      while (rs.next()) {
          // 获取每个学生的信息
          String name = rs.getString("name");
          String age = rs.getString("age");
          String addr = rs.getString("addr");
          // 拼接json格式的字符串
          // {"name":"   王五    ","age":    20      ,"addr":"      北京大兴区     "},
          json.append("{\"name\":\"");
          json.append(name);
          json.append("\",\"age\":");
          json.append(age);
          json.append(",\"addr\":\"");
          json.append(addr);
          json.append("\"},");
      }
      jsonStr = json.substring(0, json.length() - 1) + "]";
      
      
  • 拼接JSON格式的字符串太痛苦,可以使用阿里巴巴的fastjson组件,它可以将java对象转换成json格式的字符串

    • List<Student> studentList = new ArrayList<>();
      while (rs.next()) {
          // 取出数据
          String name = rs.getString("name");
          int age = rs.getInt("age");
          String addr = rs.getString("addr");
          // 将以上数据封装成Student对象
          Student s = new Student(name, age, addr);
          // 将Student对象放到List集合
          studentList.add(s);
      }
      // 将List集合转换成json字符串
      jsonStr = JSON.toJSONString(studentList);
      
      
    • 注意:使用fastjson需要引入fastjson-1.2.2.jar


基于XML的数据交换

  • 注意:如果服务器端响应XML的话,响应的内容类型需要写成:

    • response.setContentType("text/xml;charset=UTF-8");
      
  • 基于XML的数据交换,前端代码:

    • <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>使用XML完成数据交换</title>
      </head>
      <body>
      <script type="text/javascript">
          window.onload = function(){
              document.getElementById("btn").onclick = function(){
                  // 1.创建XMLHTTPRequest对象
                  var xhr = new XMLHttpRequest();
                  // 2.注册回调函数
                  xhr.onreadystatechange = function () {
                      if (this.readyState == 4) {
                          if (this.status == 200) {
                              // 服务器端响应了一个XML字符串,这里怎么接收呢?
                              // 使用XMLHTTPRequest对象的responseXML属性,接收返回之后,可以自动封装成document对象(文档对象)
                              var xmlDoc = this.responseXML
                              //console.log(xmlDoc)
                              // 获取所有的<student>元素,返回了多个对象,应该是数组。
                              var students = xmlDoc.getElementsByTagName("student")
                              //console.log(students[0].nodeName)
                              var html = "";
                              for (var i = 0; i < students.length; i++) {
                                  var student = students[i]
                                  // 获取<student>元素下的所有子元素
                                  html += "<tr>"
                                  html += "<td>"+(i+1)+"</td>"
                                  var nameOrAge = student.childNodes
                                  for (var j = 0; j < nameOrAge.length; j++) {
                                      var node = nameOrAge[j]
                                      if (node.nodeName == "name") {
                                          //console.log("name = " + node.textContent)
                                          html += "<td>"+node.textContent+"</td>"
                                      }
                                      if (node.nodeName == "age") {
                                          //console.log("age = " + node.textContent)
                                          html += "<td>"+node.textContent+"</td>"
                                      }
                                  }
                                  html += "</tr>"
                              }
                              document.getElementById("stutbody").innerHTML = html
                          }else{
                              alert(this.status)
                          }
                      }
                  }
                  // 3.开启通道
                  xhr.open("GET", "/ajax/ajaxrequest6?t=" + new Date().getTime(), true)
                  // 4.发送请求
                  xhr.send()
              }
          }
      </script>
      <button id="btn">显示学生列表</button>
      <table width="500px" border="1px">
          <thead>
          <tr>
              <th>序号</th>
              <th>姓名</th>
              <th>年龄</th>
          </tr>
          </thead>
          <tbody id="stutbody">
          <!--<tr>
              <td>1</td>
              <td>zhangsan</td>
              <td>20</td>
          </tr>
          <tr>
              <td>2</td>
              <td>lisi</td>
              <td>22</td>
          </tr>-->
          </tbody>
      </table>
      </body>
      </html>
      

AJax乱码问题

Ajax的异步与同步

版权声明:本文为优快云博主「蓦然回首却已人去楼空」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/jsdoulaoula/article/details/125889583

Ajax代码封装

JQuery封装

function JQuery(selector){
    if (typeof selector == "string") {
        if (selector.charAt(0) == "#") {
            domObj=document.getElementById(selector.substring(1));
            return new JQuery()
        }
    }
    if (typeof selector == "function") {
        window.onload=selector
    }
    this.html=function (htmlStr){
        domObj.innerHTML=htmlStr
    }
    this.click=function (fun){
        domObj.onclick=fun
    }
    this.focus=function (fun){
        domObj.onfocus=fun
    }
    this.blur=function (fun){
        domObj.onblur=fun
    }
    this.change=function (fun){
        domObj.onchange=fun
    }
    this.val=function (v){
        if (v==undefined){
            return domObj.value
        }else {
            domObj.value=v
        }
    }
    //静态方法,发送Ajax请求
    /**
     * 分析:使用ajax函数发送Ajax请求的时候,需要程序员给我们传过来什么?
     *      请求的方式(type):GET/POST
     *      请求的URL(url):url
     *      请求时提交的数据(data):data
     *      请求是异步还是同步(async):true or false
     * */
    JQuery.ajax=function (jsonArgs){
        var xhr=new XMLHttpRequest();
        xhr.onreadystatechange=function (){
            if (xhr.readyState==4){
                if (xhr.status==200){
                    //工具类封装只考虑了JSON格式
                    var jsonObj=JSON.parse(this.responseText);
                    //调用成功函数
                    jsonArgs.success(jsonObj)
                }
            }
        }
        if (jsonArgs.type.toUpperCase()=="POST"){
            xhr.open("POST",jsonArgs.url,jsonArgs.async);
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            xhr.send(jsonArgs.data);
        }
        if (jsonArgs.type.toUpperCase()=="GET"){
            xhr.open("GET",jsonArgs.url+"?"+jsonArgs.data,jsonArgs.async);
            xhr.send();
        }

    }
}
$=JQuery;
//这里有个细节,执行这个目的是为了让静态方法ajax生效
new JQuery()

测试前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script type="text/javascript" src="js/JQuery-1.0.0.js"></script>
<script type="text/javascript">
    window.onload=function (){
        document.getElementById("btn").onclick=function (){
            var username=document.getElementById("username").value
            $.ajax({
                type:"POST",
                url:"/ajax/ajaxrequest",
                data:"username="+username,
                async:true,
                //响应回来之后,拿到响应的数据
                success:function (json){
                    document.getElementById("mydiv").innerHTML=json.username
                }
            })
        }
    }


</script>

<button id="btn">发送Ajax请求</button><br>
用户名:<input type="text" id="username"><br>
<div id="mydiv"></div>
</body>
</html>

测试后端代码

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;

@WebServlet("/ajaxrequest")
public class servletTest extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String username = request.getParameter("username");
        response.getWriter().print("{\"username\":\""+username+"\"}");
    }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值