• 前端基础之AJAX


    AJAX

    什么是AJAX,简单来说就是利用JavaScript天生异步的特性,使用异步请求后台数据,从而达到不刷新网页也能局部更新页面的效果。

    原生AJAX

    JavaScript中的AJAX依赖于XMLHttpRequest对象。

    • Js也使用new创建对象:new XMLHttpRequest()
    • onreadystatechange监听事件,监听请求和响应变化,也可以理解为回调函数callback(onreadystatechange 事件被触发 5 次(0 - 4),对应着 readyState 的每个变化。)
    • readyState:请求状态值,存有 XMLHttpRequest 的状态。从 0 到 4 发生变化:
      • 0 : 请求未初始化
      • 1 : 服务器连接已建立
      • 2 : 请求已接收
      • 3 : 请求处理中
      • 4 : 请求已完成,且响应已就绪
    • status:响应状态值:200:成功响应,404
    • open(method,url,async):规定请求方式、地址、同/异步:
      • method:请求的类型;GET 或 POST
      • url:文件在服务器上的位置
      • async:true(异步)或 false(同步)(同步时不需要设置回调函数)
    • send(String)发送请求。当get时,open中的url拼好参数,send中不传参数;当post时,open中不带参数,send中传入参数(此时需要使用serHeader方法设置Content-Type属性)
    • responseText以字符串方式获得响应结果。(responseXML)以XML方式获得响应

    上个原生AJAX检测用户名的Demo:

    原生AJAX

    前端HTML:

    <h2>用户注册</h2>
    用户名:
    <input type="text" name="userName" id="userName"> <span id="info"></span>
    

    Js:

    //绑定失去焦点事件
    document.getElementById("userName").onblur = function (ev) {
        var userName = this.value;
        var xhr = new XMLHttpRequest();
        //绑定回调函数
        xhr.onreadystatechange = function (ev1) {
            if (xhr.readyState === 4 && xhr.status === 200){
                document.getElementById('info').innerText = xhr.responseText;
            }
        };
        xhr.open("get", '/AjaxServlet?userName=' + userName, true);
        xhr.send();
    };
    

    servlet后台:

    String userName = request.getParameter("userName");
    response.setContentType("text/plain;charset=utf-8");
    if ("admin".equals(userName)){//这里为了简单不从数据库获取了,直接使用固定的"admin"检验
        response.getWriter().println("用户名已存在");
    }else {
        response.getWriter().println("用户名可用");
    }
    

    JQuery封装的AJAX

    JQuery对原生AJAX进行了封装,来更方便的使用。

    请求方式 语法 说明
    GET请求 $.get(url,[data],[callback],[type]) 带[ ]为可选参数
    POST请求 $.post(url,[data],[callback],[type]) 带[ ]为可选参数
    AJAX请求 $.ajax({settings})
    GET签名 $.get({settings}) jQuery3.0新增get方法
    POST签名 $.post({settings}) jQuery3.0新增post方法

    Get/Post

    $.get(url,[data],[callback],[type])
    $.post(url,[data],[callback],[type])

    参数 说明 是否必需
    url 请求地址 必需
    data 发送给服务器端的请求参数,格式:
    方式一:key=value&key=value
    方式二:{key:value,key:value...}
    可选
    callback 回调函数:当请求成功后触发的函数 可选
    type 返回参数类型:取值可以是xml, html, script, json, text, _defaul等,默认text 可选

    使用JQuery的get/post方法进行AJAX访问:

    $('#userName').blur(function () {
        //看var不舒服换成了let
        let userName = $(this).val();
        $.get('/AjaxServlet', {userName:userName},function (result) {
            $('#info').text(result)
        });
    });
    //get/post用法一样
    

    以下情况使用post,其他情况一般使用get

    • 无法使用缓存文件(更新服务器上的文件或数据库)--提交表单数据
    • 向服务器发送大量数据(POST 没有数据量限制) ---文件上传

    使用JQuery的ajax方法进行AJAX访问:
    $.ajax({settings})

    setting参数:

    属性名 描述
    url 请求的url地址
    async true为异步,false为同步(默认为true)
    data 发送到服务器的数据,可以使键值对形式,也可以是js对象形式
    type 请求方式(默认为get)
    dataType 预期返回数据类型(xml, html, script, json, text, _default)
    success 请求成功的回调函数
    error 请求失败的回调函数

    ajax方法进行数据请求:

    AJAX方法
    $("#userName").blur(function () {
        let userName = $(this).val();
        $.ajax({
            url:"/ajaxDemoServlet",
            data:{"userName":userName,"age":4},
            async:true,
            type:"GET",
            dataType:"text",
            success:function (result) {
                $("#info").text(result);
            },
            error:function (errorRes) {
                alert("出现异常了")
            }
        })
    });
    

    JQuery 3.0 新增方法:$.get({settings})$.post({settings})用法和ajax方法类似:

    新增Get方法
    $("#userName").blur(function () {
        let userName = $(this).val();
        $.get({
            url:"/ajaxDemoServlet",
            data:{"userName":userName,"age":4},
            dataType:"text",
            success:function (result) {
                //处理正常的响应
                $("#info").text(result);
            },
            error:function (errorRes) {
                alert("出现异常了")
            }
        })
    });
    

    JSON

    Json的三种表达方式:

    类型 方式 描述
    对象类型: {K:V,K:V} 代表一个对象,有多个属性名和值
    数组/集合类型: [V1,V2,V3] 代表一个数组对象,里面的元素可以是任意类型
    混合类型: [{K:V, K:V}, {K:V, K:V}]{K:[V, V, V]} 代表数组中每个元素都是对象,一个对象某个属性值是一个数组

    Java中Json与对象互转

    使用Jackson

    添加依赖(可以手动添加三个包jackson-databind.jar jackson-core.jar jackson-annotation.jar,或者直接使用maven):

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.9</version>
    </dependency>
    

    对象转化Json字符串
    依靠ObjectMapper对象,调用writeValueAsString(Object o)方法即可把对象、数组、集合转化为Json。

    Json字符串转化为对象
    调用ObjectMapperpublic <T> T readValue(String content, Class<T> valueType)方法。

    使用FastJson工具类

    主要使用toJSONStringparseObject两个静态方法进行序列化和反序列化的操作,这里不再赘述。


    AJAX 进行用户名验证的Demo

    前端页面:

    <input type="text" id="inputUserName" name="username" class="form-control" placeholder="用户名" required autofocus>
    <span id="info"></span>
    

    完整代码:

    HTML完整代码

    使用了Bootstrap框架,请自行修改JS文件位置。

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- The above 3 meta tags *must* come test in the head; any other head content must come *after* these tags -->
        <meta name="description" content="">
        <meta name="author" content="">
    
        <title>AJAX Demo</title>
    
        <!-- Bootstrap core CSS -->
        <link href="/css/bootstrap.css" rel="stylesheet">
    
        <!-- Custom styles for this template -->
        <link href="/css/login.css" rel="stylesheet">
    
    </head>
    
    <body>
    
    <div class="container">
    
        <form class="form-signin" action="/login" method="POST">
            <div class="text-center">
                <h2 class="form-signin-heading">登录页面</h2>
            </div>
            <label for="inputUserName" class="sr-only">用户名</label>
            <input type="text" id="inputUserName" name="username" class="form-control" placeholder="用户名" required autofocus>
            <span id="info"></span>
            <label for="inputPassword" class="sr-only">密码</label>
            <input type="password" id="inputPassword" name="password" class="form-control" placeholder="密码" required>
            <div>
                <input type="text" name="checkCode" class="form-control" style=" 184px;float: left;"
                       placeholder="请输入验证码">
                <img id="captcha" style=" 84px;margin-left: 29px;" src="/CodeServlet" alt="验证码"
                     onclick="changeImg(this)">
            </div>
            <div class="checkbox">
                <label>
                    <input type="checkbox" value="remember-me"> 记住账号密码
                </label>
            </div>
            <button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
        </form>
    
    </div> <!-- /container -->
    
    </body>
    <script src="/js/jquery.js"></script>
    <script src="/js/myjs/login.js"></script>
    </html>
    
    

    JavaScript绑定事件:

    //使用JQuery绑定
    $('#inputUserName').blur(function () {
        //获取输入的userName
        let userName = $(this).val();
        if (userName === "") {
            $('#info').html('<font color="red">请输入用户名</font>');
        } else {
            //AJAX异步请求数据
            $.get('/CheckNameServlet', {userName: userName}, function (result) {
                //这里需要把字符串转化为boolean
                if (!JSON.parse(result.flag)) {
                    $('#info').html('<font color="red">用户名已存在</font>');
                } else {
                    $('#info').html('<font color="green">✔</font>');
                }
                console.log(result);
            },'json')
        }
    });
    

    然后是后端控制层:

    @WebServlet("/CheckNameServlet")
    public class CheckNameServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/plain;charset=utf-8");
            String userName = request.getParameter("userName");
            UserService us = new UserService();
            boolean flag = us.queryUserByName(userName);
            Map<String,String> map = new HashMap<>();
            map.put("flag", String.valueOf(flag));//返回布尔值好像还不如返回 0 或 1
            //这里使用了Jackson转化为Json
            response.getWriter().print(new ObjectMapper().writeValueAsString(map));
            //System.out.println(map);
        }
    }
    

    后台业务层:

    public class UserService {
        public boolean queryUserByName(String name){
            UserDao ud = new UserDao();
            List<User> list = ud.queryUserByName(name);
            if (list!=null && list.size()>0){
                return false;
            }else {
                return true;
            }
        }
    }
    
    

    后台持久层:

    public class UserDao {
        public List<User> queryUserByName(String name) {
            JdbcTemplate jt = DataSourceUtil.getJdbcTemplate();
            String sql = "select * from t_user where username = ?";//这个sql不太好,查询了太多无用数据
            return jt.query(sql, new BeanPropertyRowMapper<>(User.class), name);
        }
    }
    
    

    最终效果:

    初始页面:

    初始页面

    不输入的情况下用户名框失去焦点时:

    失去焦点

    输入已存在用户名时:

    已存在用户名

    用户名可用时:

    用户名可用


    至此,AJAX简单介绍完毕

  • 相关阅读:
    《UIP在NIOS上的移植》
    切勿使用:指向局部变量的指针作为函数的返回指针!
    Oeacle创建表空间
    Oracle SQL 语言分类
    线程整理
    输入输出
    异常处理
    哈希算法
    java链表
    课上重点整理
  • 原文地址:https://www.cnblogs.com/lixin-link/p/11229177.html
Copyright © 2020-2023  润新知