请选择 进入手机版 | 继续访问电脑版
MSIPO技术圈 首页 IT技术 查看内容

Ajax异步响应

2023-07-13

Ajax

概念

  • Asynchronous JavaScript And XML:异步的js和xml: 客户端与服务器端进行数据交互。

异步与同步

  • ①同步

    多个操作按顺序执行,前面的操作没有完成,后面的操作就必须等待。所以同步操作通常是串行的。

    #②异步

    多个操作相继开始并发执行,即使开始的先后顺序不同,但是由于它们各自是在自己独立的进程或线程中完成,所以互不干扰,**谁也*不用等*

异步的使用场景

  • 百度输入框
  • 验证用户名是否存在
  • 异步分页
  • 实现前后台分离项目(基石)

前台后台代码存放不同的服务器,这样既减轻了服务器的压力,也在服务器宕机时还能提供页面展示,只不过没有数据

传输数据类型

  • 异步

    • 字符串
    • xml:前台得到的是一个document对象; xml配置
    • json:特殊的数据格式,获取的是字符串,需要使用eval函数执行一次,得到json对象’’
  • 同步

    • 响应的都是以整个HTML页面

1.2 原生Ajax

对于Ajax技术有了充分的认知了,我们接下来通过代码来演示Ajax的效果。此处我们先采用原生的Ajax代码来演示。因为Ajax请求是基于客户端发送请求,服务器响应数据的技术。所以为了完成快速入门案例,我们需要提供服服务器端和编写客户端。

  • 服务器端

    因为我们暂时还没学过服务器端的代码,所以此处已经直接提供好了服务器端的请求地址,我们前端直接通过Ajax请求访问该地址即可。后台服务器地址:http://yapi.smart-xwork.cn/mock/169327/emp/list

    上述地址我们也可以直接通过浏览器来访问,访问结果如图所示:只截取部分数据

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kNYCMCyW-1688730471077)(Ajax.assets/1669105963948.png)]

  • 客户端

    客户端的Ajax请求代码如下有如下4步,接下来我们跟着步骤一起操作一下。

    第一步:首先我们再VS Code中创建AJAX的文件夹,并且创建名为01. Ajax-原生方式.html的文件,提供如下代码,主要是按钮绑定单击事件,我们希望点击按钮,来发送ajax请求

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>原生Ajax</title>
    </head>
    <body>
        
        <input type="button" value="获取数据" onclick="getData()">
    
        <div id="div1"></div>
        
    </body>
    <script>
        function getData(){
         
        }
    </script>
    </html>
    

    第二步:创建XMLHttpRequest对象,用于和服务器交换数据,也是原生Ajax请求的核心对象,提供了各种方法。代码如下:

    //1. 创建XMLHttpRequest 
    var xmlHttpRequest  = new XMLHttpRequest();
    

    第三步:调用对象的open()方法设置请求的参数信息,例如请求地址,请求方式。然后调用send()方法向服务器发送请求,代码如下:

    //2. 发送异步请求
    xmlHttpRequest.open('GET','http://yapi.smart-xwork.cn/mock/169327/emp/list');
    xmlHttpRequest.send();//发送请求
    

    第四步:我们通过绑定事件的方式,来获取服务器响应的数据。

    //3. 获取服务响应数据
    xmlHttpRequest.onreadystatechange = function(){
        //此处判断 4表示浏览器已经完全接受到Ajax请求得到的响应, 200表示这是一个正确的Http请求,没有错误
        if(xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
            document.getElementById('div1').innerHTML = xmlHttpRequest.responseText;
        }
    }
    

    最后我们通过浏览器打开页面,请求点击按钮,发送Ajax请求,最终显示结果如下图所示:

    并且通过浏览器的f12抓包,我们点击网络中的XHR请求,发现可以抓包到我们发送的Ajax请求。XHR代表的就是异步请求

Ajax:问题是嵌套地狱

		$.function(){再去嵌套2层或3层的$.ajax()},回导致代码的阅读性,非常差;

嵌套地域代码欣赏

 $(function() {
            $("button:eq(0)").click(function() {
                // $.get(url,data,callback,type)
                //url 请求的服务器地址
                //data 请求携带的参数
                //callback 当前服务器执行成功时的回调函数
                //type 请求与响应数据的格式(注意格式不符会出错)
                //使用ajax发送get请求
                $.get("/ajax", {
                    "username": "zhangsan"
                }, function(res) {
                    //result 就是一个变量 保存返回的数据
                    $("button:eq(0)").html(res)
                    $.post("/xxx"),{}....
                }, "text/json")
            })
            $("button:eq(1)").click(function() {
                //$.post(url,data,callback,type)
                $.post("ajax", {
                    "username": "zhangsan"
                }, function(res) {
                    //result 就是一个变量 保存返回的数据
                    $("button:eq(1)").html(res)
                }, "text")
            })
            $("button:eq(2)").click(function() {
                //$.ajax({url,settings})
                //是通用方法 可以通过参数的形式 修改请求的相应配置  
                //通过json形式进行配置设置
                $.ajax({
                    asynctrue//是否异步执行
                    "type": "post", //post 定义请求方式
                    "url": "ajax",
                    "data": {
                        "username": "ajax"
                    },
                    "dataType": "text",
                    "success": function(data) {
                        alert(data);
                    },
                    "error": function() {
                        alert("出错了")
                    }

                })

            })
        })

二.Axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

axios和ajax区别有:

​ 1、理论区别;2、逻辑区别。理论上,axios是通过Promise实现对ajax技术的一种封装,就像jquery对ajax的封装一样,ajax技术实现了局部数据的刷新,axios实现了对ajax的封装,axios有的ajax都有,ajax有的axios不一定有。

引用库:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  1. axios

axios是VUE 之父 尤雨溪大神推荐使用的,它也是对原生XHR的封装。它有以下几大特性:

  • 可以在node.js中使用
  • 提供了并发请求的接口
  • 支持Promise API
  • 简单使用

三.axios使用

(1)get请求方式

将请求参数拼接到url中

const axios = require('axios');
 
//get():get请求,不能发post;
'/user':表示客户端请求的url,去/user请求,一般去servlet
{}params:{ID:12345} 客户端携带的参数,发服务器发的数据;
axios.get('/user', {
    params: {
      ID: 12345
    })
  .then(function (data) {   	//成功;
       console.log(data);  //成功代码
  })
  .catch(function (error) {    
       console.log(error); //失败代码
  })

(2)post请求方式

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

执行多个并发请求

function getUserAccount() {
  return axios.get('/user/12345');
} 
function getUserPermissions() {
  return axios.get('/user/12345/permissions');
} 
axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    //2个post请求现已完成
  }));

(2)合并方式

我们给它指定具体的get/

axios({
    method: 'GET',
    url: url,
    "params":{
        具体的参数
    }
})
.then(res => {console.log(res)})
.catch(err => {console.log(err)})

四.案例

①前端代码

axios({
        "method":"post",
        "url":"/demo/AjaxServlet?method=commonParam",
           "params":{
            "userName":"tom",
            "userPwd":"123456"
           }
        }
     ).then(function (response) {
            console.log(response);
        }).catch(function (error) {
            console.log(error);
        });

②后端代码

public class AjaxServlet extends ModelBaseServlet {
    protected void commonParam(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userName = request.getParameter("userName");
        String userPwd = request.getParameter("userPwd");

        System.out.println("userName = " + userName);
        System.out.println("userPwd = " + userPwd);

        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("服务器端返回普通文本字符串作为响应");
    }
}

③axios程序接收到的响应对象结构

属性名作用
config调用axios(config对象)方法时传入的JSON对象
data服务器端返回的响应体数据
headers响应消息头
request原生JavaScript执行Ajax操作时使用的XMLHttpRequest
status响应状态码
statusText响应状态码的说明文本

④服务器端处理请求失败后

catch(function (error) {     // catch()服务器端处理请求出错后,会调用

    console.log(error);         // error就是出错时服务器端返回的响应数据
    console.log(error.response);        // 在服务器端处理请求失败后,获取axios封装的JSON格式的响应数据对象
    console.log(error.response.status); // 在服务器端处理请求失败后,获取响应状态码
    console.log(error.response.statusText); // 在服务器端处理请求失败后,获取响应状态说明文本
    console.log(error.response.data);   // 在服务器端处理请求失败后,获取响应体数据

});

可以看到,response对象的结构还是和then()函数传入的回调函数中的response是一样的:

五.JSON数据封装和解析

概述

JavaScript Object Notation, JS对象格式)是一种轻量级的数据交换格式。

  • js提供的一种数据交换的格式,一般情况,都是再后台拼接json数据,响应前台.前台使用js代码就可以方便操作json
  • 当前台请求设置dataType为json时,会自动将服务返回的数据转换为json对象,如果在转换时失败,则会出现明明服务执行但仍然调用失败方法回调

语法格式:

​ {“键”:“值”,“键”:“值”,“键”:“值”,“键”:“值”,…n}

​ params:{“uname:'yh”}

json数组形式:

​ [{“uname”:“方言”,“age”:16},{“uname”:“晨阳”,“age”:28}]

数据规范

  • 定义json数据

    • 格式必须使用{}包括起来,当做对象来使用,对象包含属性和值,如果是属性,必须使用双引号括起来,属性与值之间使用冒号,属性与属性之间使用逗号
  • 获取json数据的方式

    • 对象名.属性名

Jackson

1.将java对象转化成json字符串并写入到目标源中

User user=new User(1,“张三”); JAVA对象;

{“id”:“1”,“uname”:“张三”}

  1. writeValue(File file, Objcet obj); – 将obj对象的内容写入File文件中
  2. writeValue(Writer writer, Object obj); – 将obj对象写入到Writer 字符流对象中
  3. writeValue(OutputStream output, Object obj); – 将obj对象写入OutputStream 字节流对象中

demo测试:

public class Test01 {
    public static void main(String[] args) throws JsonProcessingException {
        //1.创建了一个JAVA的对象user,第一步,相当于我们从数据库,来查询,返回到客户端;
//        User user=new User(1,"zhangsan","123456");
//        User user2=new User(2,"李四","654321");
//        ArrayList<User>list=new ArrayList<>();
//        list.add(user);
//        list.add(user2);
        
//        User[]us={new User(1,"zhangsan","123456"),new User(2,"李四2","654321")};
//        List list= Arrays.asList(us);
        //将来肯定是dao层返回数据;

        //2.创建一个ObjectMapper对象;
        ObjectMapper mapper=new ObjectMapper();
        //3.方法;JAVA对象,作为一个字符串输出了,这个字符串里面放的是java对象;
        //写值 做为字符串;
//        String s = mapper.writeValueAsString(user);
        String s=mapper.writeValueAsString(list);

        System.out.println(s);
    }
}
  1. JSON转为Java对象

    {“uanme”:“张三”,“age”:28} —>JAVA对象格式;

    User user=new User()

1、导入jackson的相关jar包

2、创建Jackson核心对象 ObjectMapper

3、调用ObjectMapper的相关方法进行转换:readValue( json字符串数据 ,Class)

①前端代码

let data=success.data;
$('#uinfo').html(data.msg).css('color','red');

②后端代码

#[1]加入json包

路径WEB-INF下的lib包

resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//为什么使用Map,天然好处:键值对的方式;
Map<String,String> map=new HashMap<>();

if(user!=null){   
    //服务器发回数据到客户端;存到map
    map.put("msg","\"用户名已经存在,不能使用该用户名!\"");
    map.put("status","200");
    map.put("userExists","true");
    //resp.getWriter().println(map);
}else{
    map.put("msg","√");
    map.put("status","250");
    map.put("userExists","false");
}
//调用jackson对象;
ObjectMapper mapper=new ObjectMapper();

mapper.writeValue(resp.getWriter(),map);
set=utf-8");
//为什么使用Map,天然好处:键值对的方式;
Map<String,String> map=new HashMap<>();

if(user!=null){   
    //服务器发回数据到客户端;存到map
    map.put("msg","\"用户名已经存在,不能使用该用户名!\"");
    map.put("status","200");
    map.put("userExists","true");
    //resp.getWriter().println(map);
}else{
    map.put("msg","√");
    map.put("status","250");
    map.put("userExists","false");
}
//调用jackson对象;
ObjectMapper mapper=new ObjectMapper();

mapper.writeValue(resp.getWriter(),map);

相关阅读

手机版|MSIPO技术圈 皖ICP备19022944号-2

Copyright © 2023, msipo.com

返回顶部