• javaweb之ajax异步交互


    一、概念

    1、传统网站存在的问题

    传统的页面交互是Servlet 调用完业务逻辑层后将数据存储到域对象中,然后跳转到指定的 jsp 页面,在页面上使用 EL表达式 和JSTL 标签库进行数据的展示。该模式存在以下问题:

    • 网速比较慢的情况下,页面加载时间长,用户需等待
    • 表单提交后,如果有一项内容不合格,需要重新填写所有表单内容
    • 页面跳转,重新加载页面,造成资源浪费,增加用户等待时间
    2、Ajax介绍
    • AJAX (Asynchronous JavaScript And XML):异步的 JavaScript 和 XML。其中JavaScript 表明该技术和前端相关;XML 是指以此进行数据交换。它是浏览器提供的一套方法,可以实现页面无刷新更新数据,提高浏览网站应用的体验。
    • 通过使用Ajax技术,它可以和服务器进行通信,以达到使用 HTML+AJAX来替换JSP页面,即浏览器发送请求servlet,servlet 调用完业务逻辑层后将数据直接响应回给浏览器页面,页面使用 HTML 来进行数据展示。
    3、同步与异步
    • 同步
      浏览器页面在发送请求给服务器,在服务器处理请求的过程中,浏览器页面不能做其他的操作。只能等到服务器响应结束后才能,浏览器页面才能继续做其他的操作。
    • 异步
      浏览器页面发送请求给服务器,在服务器处理请求的过程中,浏览器页面还可以做其他的操作。
    4、应用场景
    • 页面上的上拉加载与下拉刷新
    • 列表数据无刷新分页
    • 表单项离开焦点数据验证(避免页面跳转重新填写表单)
    • 搜索框提示文字下拉列表(如百度的搜索提示 )

    二、Ajax使用

    1、 XMLHttpRequest 对象
    (1)介绍

    所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
    XMLHttpRequest 用于在后台与服务器交换数据。它可以在不向服务器提交整个页面的情况下,实现局部更新网页。
    XMLHttpRequest的对象用于客户端和服务器之间的异步通信。
    它执行以下操作:

    • 在后台从客户端发送数据
    • 从服务器接收数据
    • 更新网页而不重新加载。
    (2)创建 XMLHttpRequest 对象的语法
    var http=new XMLHttpRequest();
    
    • 1
    (3)XMLHttpRequest对象的属性

    XMLHttpRequest对象的常见属性如下:

    属性描述
    onreadystatechange
    存储函数(或函数名),每当readyState的属性改变时,就会调用该函数。
    readyState存有的XMLHttpRequest的状态从0到4发生变化。
    0:请求未初始化
    1:服务器连接已建立
    2:请求已接收
    3:请求处理中
    4:请求已完成,且响应已就绪
    responseText以文本形式返回响应。
    responseXML以XML格式返回响应
    status
    将状态返回为数字(例如,“Not Found”为404,“OK”为200)
    statusText
    以字符串形式返回状态(例如,“Not Found”或“OK”)
    (4)XMLHttpRequest对象的方法

    XMLHttpRequest对象的重要方法如下:

    方法描述
    abort()
    取消当前请求。
    getAllResponseHeaders()
    以字符串形式返回完整的HTTP标头集。
    getResponseHeader( headerName )
    返回指定HTTP标头的值。
    void open(method,URL)打开指定获取或交的方法和URL的请求。
    void open(method,URL,async)与上面相同,但指定异步或不。
    void open(method,URL,async,userName,password)
    与上面相同,但指定用户名和密码。
    void send(content)发送获取请求。
    setRequestHeader( label,value)
    将标签/值对添加到要发送的HTTP标头。
    2、 AJAX XHR-请求
    (1) AJAX 的工作原理

    AJAX 使用的 XMLHttpRequest 的对象与服务器通信, AJAX 的工作原理如图:
     在这里插入图片描述
    ajax请求流程如下:

    • 用户从 UI 发送请求,JavaScript 中调用 XMLHttpRequest 对象。
    • HTTP 请求由 XMLHttpRequest 对象发送到服务器。
    • 服务器使用 JSP,PHP,Servlet,ASP.net 等与数据库交互。
    • 检索数据。
    • 服务器将 XML 数据或 JSON 数据发送到 XMLHttpRequest 回调函数。
    • HTML 和 CSS 数据显示在浏览器上。
    (2) 向服务器发送请求

    当你的页面全部加载完毕后,客户端会通过 XMLHttpRequest 对象向服务器请求数据,服务器端接受数据并处理后,向客户端反馈数据。如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的open()和send()方法:

     //创建Ajax对象
    var http=new XMLHttpRequest();
    //设置Ajax的请求地址与请求方式
     http.open("get","http://localhost:8080/GetUserInfoServlet");
    //发送请求
    http.send();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    3、 AJAX XHR-响应

    由于 HTTP 响应是由服务端发出的,并且服务器做出响应需要时间(比如网速慢等原因),所以需要监听服务器响应的状态,然后才能进行处理。

    • 状态行
      xhr.status状态码,如200,304,404等;
    • 响应主体
      xhr.responseText与xhr.responseXML都表示响应主体。
    属性描述
    responseText获得字符串形式的响应数据。
    responseXML获得 XML 形式的响应数据。
    4、 AJAX - onreadystatechange 事件

    当发送一个请求后,客户端需要确定这个请求什么时候会完成,因此,XMLHttpRequest对象提供了onreadystatechange事件机制来捕获请求的状态,继而实现响应。
    当请求被发送到服务器时,执行一些基于响应的任务,每当readyState改变时,就会触发onreadystatechange事件。readyState属性存有 XMLHttpRequest 的状态信息。

    属性描述
    onreadystatechange 存储函数(或函数名),每当readyState属性改变时,就会调用该函数。
    readyState

    存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

    • 0: 请求未初始化,还没有调用 open()

    • 1: 请求已经建立,但是还没有发送,还没有调用 send()

    • 2: 请求已发送,正在处理中(通常现在可以从响应中获取内容头)

    • 3: 请求在处理中;通常响应中已有部分数据可用了,没有全部完成

    • 4: 响应已完成;可以获取并使用服务器的响应了

    status 200: "OK"
    404: 未找到页面

    回调函数事件

    		http.onreadystatechange=function () {
            //readyState 0=>初始化 1=>载入 2=>载入完成 3=>解析 4=>完成
            if(this.readyState==4&&this.status==200){
              var responseText=this.responseText
              console.log('返回结果:'+responseText)
            }
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、Ajax实例

    1、Ajax之get请求

    (1)GetUserInfoServlet接口

    @WebServlet("/GetUserInfoServlet")
    public class GetUserInfoServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doGet(req,resp);
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html;charset=utf-8");
    
            String username=req.getParameter("username");
            String password=req.getParameter("password");
    
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
    
            String content= JSON.toJSONString(user);
    
            PrintWriter writer = resp.getWriter();
            writer.write(content);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    (2)ajax页面请求

        function getUserInfo() {
          var username = document.getElementById("username").value;
          var password = document.getElementById("password").value;
          //创建Ajax对象
          var http=new XMLHttpRequest();
          //设置Ajax的请求地址与请求方式
          var params='username='+username+'&password='+password;
          http.open("get","http://localhost:8080/GetUserInfoServlet?"+params);
          //发送请求
          http.send();
          //获取响应数据
          http.onreadystatechange=function () {
            //readyState 0=>初始化 1=>载入 2=>载入完成 3=>解析 4=>完成
            if(this.readyState==4&&this.status==200){
              var responseText=this.responseText
              console.log('返回结果:'+responseText)
              var result=JSON.parse(responseText);
              console.log('解析结果:password:'+result.password+' username:'+result.username)
            }
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    2、Ajax之post请求

    (1)GetUserInfoServlet接口

    @WebServlet("/UserLoginServlet")
    public class UserLoginServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html;charset=utf-8");
    
            //解析参数
            InputStreamReader insr = new InputStreamReader(req.getInputStream(),"utf-8");
            String res = "";
            int respInt = insr.read();
            while(respInt!=-1) {
                res +=(char)respInt;
                respInt = insr.read();
            }
            User user=JSON.parseObject(res,User.class);
            //返回结果
            Result result = new Result();
            if(user.getUsername()==null||user.getUsername().isEmpty()){
                result.setSuccess(false);
                result.setErrorCode(-1);
                result.setErrorMsg("请输入用户名");
            }else if(user.getPassword()==null||user.getPassword().isEmpty()){
                result.setSuccess(false);
                result.setErrorCode(-1);
                result.setErrorMsg("请输入密码");
            }else if(!user.getUsername().equals("admin")||!user.getPassword().equals("admin")){
                result.setSuccess(false);
                result.setErrorCode(-1);
                result.setErrorMsg("用户名或者密码错误");
            }else {
                result.setSuccess(true);
            }
            PrintWriter writer = resp.getWriter();
            writer.write(JSON.toJSONString(result));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    (2)ajax页面请求

    function login() {
          var username = document.getElementById("username").value;
          var password = document.getElementById("password").value;
          //创建Ajax对象
          var http=new XMLHttpRequest();
          //设置Ajax的请求地址与请求方式
          http.open("post","http://localhost:8080/UserLoginServlet");
          //设置请求的参数格式的类型(post请求必须要设置)
          // http.setRequestHeader('Content-type','application/x-www-form-urlencoded') username=123&password=344
          http.setRequestHeader('Content-type','application/json')
          //发送请求
          http.send(JSON.stringify({
              username:username,
              password:password
          }));
          //获取响应数据
          http.onreadystatechange=function () {
            //readyState 0=>初始化 1=>载入 2=>载入完成 3=>解析 4=>完成
            if(this.readyState==4&&this.status==200){
              var responseText=this.responseText
              console.log('返回结果:'+responseText)
              var result=JSON.parse(responseText);
              if(result.success){
                 alert('登录成功')
              }else {
                 alert(result.errorMsg)
              }
            }
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    【星海出品】flask (二) request替代VUE测试flask接口
    MIT6.830-lab4-SimpleDB Transactions(数据库的事务LockManager、事务操作、死锁处理)
    沉浸式视听体验:全景声技术是如何实现的?
    Leetcode 15:三数之和
    Linux下的代码编辑器——vim
    【Java八股文总结】之JVM
    Java中通过反射获取自定义注解中标识的对象属性信息(若依@Excel注解示例)
    在Docker中安装nacos
    1.初始cmake
    一款简化Python自然语言处理的开源库
  • 原文地址:https://blog.csdn.net/u010520146/article/details/127577646