Ajax,Json,Axios(十)

·  阅读 30

Ajax

服务器渲染

点击超链接【浏览器窗口】——>发送请求——>servlet——>Thymeleaf——>服务器端渲染,完整页面:HTML格式的数据——>响应——>浏览器窗口内容整体被响应数据的完整页面所替换【浏览器窗口】

Ajax渲染【局部更新】

Ajax程序发出请求【触发函数】——Servlet——数据片段【JSON格式的数据】——响应——Ajax程序获得响应数据——Ajax程序修改页面局部

前后端分离

​ 真正的前后端分离式前端项目和后端项目分服务器部署,在这里先理解为彻底舍弃服务器端渲染,数据全部通过Ajax方式以JSON格式来传递

同步和异步的区别

​ Ajax本身就是Asynchronous JavaScript And XML的缩写,直译为:异步的JavaScript和XML。在实际应用中Ajax指的是:不刷新浏览器窗口,不做页面跳转,局部更新页面内容的技术。

同步

​ 多个操作按顺序执行,前面的发操作没有完成,后面的操作就必须等待,所以操作通常是串行的。【如服务器渲染】

异步

​ 多个操作相继并发执行,即使开始的先后顺序不同,但是由于他们各自实在自己独立的进程或线程中完成,所以互不干扰,谁也不用等待谁。【如Ajax渲染】

应用场景

  1. 网站首页使用Ajax加载数据,可以提高页面响应效率;
  2. 搜索框、文本框中使用Ajax检索数据,可以提高用户体验度;
  3. ...

语法

原生的Js发送Ajax请求

请求报文【请求行,请求头,空行,请求体】

请求行:由方法字段、URL 字段 和HTTP 协议版本字段 3 个部分组成,他们之间使用空格隔开。

请求头:由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息。

空行:最后一个响应头部之后是一个空行,发送回车符和换行符,通知服务器以下不再有响应头部。

请求体:请求体不在 GET 方法中使用,而是在POST 方法中使用。POST 方法适用于需要客户填写表单的场合。与请求包体相关的最常使用的是包体类型 Content-Type 和包体长度 Content-Length;

​ 报文结构复杂,不可能手写。好在浏览器为我们提供了一个XMLHttpRequest对象。XMLHttpRequest对象是AJAX中非常重要的对象,所有的AJAX操作都是基于该对象的。

XMLHttpRequest获取方式

方式一:var xhr = new XMLHttpRequest():目前主流浏览器都支持

方式二:var xhr = new ActiveXObject("Msxml2.XMLHTTP"):IE6支持的方式

方式三:var xhr = new ActiveXObject("Microsoft.XMLHTTP"):IE5.5以下支持的方式

通用方法:

//获取XMLHttpRequest的通用方法
function getXMLHttpRequest(){
	var xhr;
	try{
		//大部分浏览器都支持
		xhr = new XMLHttpRequest();
	}catch(e){
		try{
			//如果不支持,在这里捕获异常并且采用IE6支持的方式
			xhr = new ActiveXObject("Msxml2.XMLHTTP");
		}catch(e){
			//如果还不支持,在这里捕获异常并采用IE5支持的方式
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	return xhr;
}
复制代码
XMLHttpRequest方法
  • open(method,url,async):用于设置请求的基本信息,接收三个参数。

    • 参数一:method

      接收一个字符串,表明请求的方法:get或post

    • 参数二:url

      请求的地址,接收一个字符串

    • 参数三:Assync

      发送的请求是否为异步请求,接收一个布尔值。① true 是异步请求 ② false 不是异步请求(同步请求)

  • **send(string):**用于将请求发送给服务器,可以接收一个参数

    • string参数

      该参数只在发送post请求时需要。用于设置请求体

  • setRequestHeader(header,value):用于设置请求头

    • 参数一:header参数

      字符串类型,要设置的请求头的名字

    • 参数二:value参数

      字符串类型,要设置的请求头的值

XMLHttpRequest对象的属性:
  • readyState

    • 描述XMLHttpRequest的状态
    • 一共有五种状态分别对应了五个数字:
      • 0 :请求尚未初始化,open()尚未被调用
      • 1 :服务器连接已建立,send()尚未被调用
      • 2 :请求已接收,服务器尚未响应
      • 3 :请求已处理,正在接收服务器发送的响应
      • 4 :请求已处理完毕,且响应已就绪。
  • status

    • 请求的响应码

      • 200 响应成功

      • 404 页面为找到

      • 500 服务器内部错误

        … … … …

  • onreadystatechange

    • 该属性需要指向一个函数
    • 该函数会在readyState属性发生改变时被调用
  • responseText

    • 获得字符串形式的响应数据。
  • responseXML(用的比较少)

    • 获得 XML 形式的响应数据。

JQuery发送Ajax请求

<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>
<script>
//ajax基本语法
$.ajax({
    url:"${pageContext.request.contextPath}/TestAjaxServlet",       //请求路径
    type:"POST",                                    //请求方式【GET|POST|PUT|DELETE】
    // data:"stuName=yanfei&stuAge=18",             //请求参数
    data:{"stuName":"chengbo","stuAge":18},         //请求json参数
    dataType:"json",                                //服务器预期返回数据类型[text|json|jsonp]
    success:function(rs){                           //回调函数【请求成功】
        alert("rs:"+rs.stuAge);
    },
    error:function(){                               //回调函数【请求失败】
        alert("请求失败!");
    }
});
//ajax简写语法
//$.get(url,[data],[success:fn],[dataType]):以GET请求方式,发送请求
//$.post(url,[data],[success:fn],[dataType]):以POST请求方式,发送请求
//$.getJSON(url,[data],[success:fn]):以GET请求方式,发送请求;并以json格式响应数据【dataType=json】
</script>
复制代码

Vue发送Ajax请求

Axios

JSON

简介

JSON全称:JavaScript Object Notation【JS提供的一种轻量级的数据交换格式】

本质:JavaScript对象,与字符串可以进行转换

作用:JSON可以在不同语言,不同生态之间进行数据交互

使用

语法:

//定义json对象
var jsons = {
    "key1":"abc", // 字符串类型
    "key2":1234,  // Number
    "key3":[1234,"21341","53"], // 数组
    "key4":{                    // json类型
        "key4_1" : 12,
        "key4_2" : "kkk"
    },
    "key5":[{                  // json数组
        "key5_1_1" : 12,
        "key5_1_2" : "abc"
    },
        {
            "key5_2_1" : 41,
            "key5_2_2" : "bbj"
        }]
};
//abc
// alert(jsons.key1);
//53
// alert(jsons.key3[2]);
//kkk
// alert(jsons.key4.key4_2);
//bbj
alert(jsons.key5[1].key5_2_2);
复制代码

类型转换

在Js语言环境下,Json对象与Json字符串转换问题

  • Json对象->Json字符串
    • var jsonString = JSON.stringify(JsonObj);
  • Json字符串->Json对象
    • var jsonObj = JSON.parse(jsonString);

在Java语言环境下,Java对象【JavaBean&List&Map】与Json字符串转换问题

使用Google下Gson工具

  • Java对象->Json字符串

    • Gson gson = new Gson(); //使用toJson()方法,将javaBean转换为Json字符串 String jsonString = gson.toJson(student);//参数是对象
    • Gson gson = new Gson(); String s = gson.toJson(list); //参数是对象的可变数组
  • Json字符串->Java对象【JavaBean&List&Map】

    • Student student1 = gson.fromJson(jsonString, Student.class);//单个JSON对象字符串转换
    • List<Student> list1 = gson.fromJson(s, new TypeToken<List<Student>>() { }.getType());//多个JSON对象字符串转换

代码

@Test
public void testJavaBeanAndJsonString(){
    //将JavaBean->JsonString
    Student student = new Student(1001,"yanfei",18);
    Gson gson = new Gson();
    //使用toJson()方法,将javaBean转换为Json字符串
    String jsonString = gson.toJson(student);           //String str = "{\"id\":1001,\"stuName\":\"yanfei\"}";
    System.out.println("jsonString = " + jsonString);
    //将JsonString->JavaBean
    Student student1 = gson.fromJson(jsonString, Student.class);
    System.out.println("student1 = " + student1.getStuName());

}
@Test
public void testListAndJsonString(){
    //List<Student> -> jsonString
    List<Student> list = new ArrayList<>();
    list.add(new Student(1001,"yanfei",18));
    list.add(new Student(1002,"ligen",19));
    list.add(new Student(1003,"chengbo",38));
    Gson gson = new Gson();
    String s = gson.toJson(list);    //[{"":""},{"":""},{"":""}]  或{{"":""},{"":""},{"":""}}
    System.out.println("s = " + s);
    //jsonString -> List<Student>
    List<Student> list1 = gson.fromJson(s, new TypeToken<List<Student>>() {
    }.getType());
    for (Student student : list1) {
        System.out.println("student = " + student.getStuName());
    }
}
@Test
public void testMapAndJsonString(){
    Map<String,Student> map = new HashMap<>();
    map.put("yanfei",new Student(1001,"yanfei",18));
    map.put("ligen",new Student(1002,"ligen",19));
    map.put("chengbo",new Student(1003,"chengbo",38));
    //将map->jsonString
    Gson gson = new Gson();
    String s = gson.toJson(map);
    System.out.println("s = " + s);
    //jsonString->Map<String,Student>
    Map<String,Student> map1 = gson.fromJson(s, new TypeToken<Map<String, Student>>() {
    }.getType());
    System.out.println(map1.get("chengbo").getStuAge());
}
复制代码

Axios

简介

​ 使用原生的JavaScript程序执行Ajax极其繁琐,所以一定要使用框架来完成。而Axios就是目前最流行的前端Ajax框架。

​ Axios官网:www.axios-js.com/

基本用法

引入方式和Vue一样,导入对应的*.js文件即可。

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
复制代码

我们可以把这个axios.min.js文件下载下来保存到本地来使用。

在前端页面引入开发环境

<script type="text/javascript" src="/demo/static/vue.js"></script>
<script type="text/javascript" src="/demo/static/axios.min.js"></script>
复制代码

需要先引入Vue。

发送普通请求参数

1 html
<div id="app">
    <button @click="commonParam">普通请求参数</button>
</div>
复制代码
2 Vue+axios代码:
var vue = new Vue({
    "el":"#app",
    "data":{
        "message":""
    },
    "methods":{
        commonParam(){
            //使用axios发送异步请求
            axios({
                "method":"post",
                "url":"demo01",
                "params":{
                    "userName":"tom",
                    "userPwd":"123456"
                }
            }).then(response => {
                //then里面是处理请求成功的响应数据
                //response就是服务器端的响应数据,是json类型的
                //response里面的data就是响应体的数据
                this.message = response.data
            }).catch(error => {
                //error是请求失败的错误描述
                //error.response就是请求失败时候的响应信息
                console.log(error.response)
            })
        }
    }
})
</script>
复制代码

效果:所有请求参数都被放到URL地址后面了,哪怕我们现在用的是POST请求方式。

3 后端代码
package com.atguigu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Chunsheng Zhang
 * 日期2021-05-21  09:15
 */
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //1. 接收请求参数userName和userPwd
        String userName = request.getParameter("userName");
        String userPwd = request.getParameter("userPwd");
        System.out.println(userName + ":" + userPwd);

        //模拟出现异常
        //int num = 10/0;

        //2. 向浏览器响应数据
        response.getWriter().write("hello world!!!");
    }
}
复制代码
4 axios程序接收的响应对象结构
属性名作用
config调用axios(config对象)方法时传入的JSON对象
data服务器端返回的响应体数据
headers响应消息头
request原生JavaScript执行Ajax操作时使用的XMLHttpRequest
status响应状态码
statusText响应状态码的说明文本
5 服务器端处理请求失败后
catch(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);   // 在服务器端处理请求失败后,获取响应体数据

});
复制代码

在给catch()函数传入的回调函数中,error对象封装了服务器端处理请求失败后相应的错误信息。其中,axios封装的响应数据对象,是error对象的response属性。response对象的结构还是和then()函数传入的回调函数中的response是一样的。

什么是回调函数?

开发人员声明,但是调用时交给系统来调用。像单击响应函数、then()、catch()里面传入的都是回调函数。回调函数是相对于普通函数来说的,普通函数就是开发人员自己声明,自己调用:

function sum(a, b) {
return a+b;
}

var result = sum(3, 2);
console.log("result="+result);
复制代码

发送JSON请求体

1 html
<button @click="sendJsonBody">请求体JSON</button>
复制代码
2 Vue+axios代码:
<script>
    var vue = new Vue({
        "el":"#app",
        "data":{
            "message":""
        },
        "methods":{
            sendJsonBody(){
                axios({
                    "method":"post",
                    "url":"demo02",
                    "data":{
                        "username":"奥巴马",
                        "password":"123456",
                        "id":1,
                        "nickname":"圣枪游侠"
                    }
                }).then(response => {
                    console.log(response.data)
                })
            }
        }
    })
</script>
复制代码
3 后端代码

(1)加入Gson包

GSON是JSON数据解析和生成工具,它可以帮助我们将数据在JSON字符串和Java对象之间互相转换。

(2)User类

package com.atguigu.user;

/**
 * 包名:com.atguigu.user
 *
 * @author Chunsheng Zhang
 * 日期2021-05-21  10:18
 */
public class User {
    private Integer id;
    private String username;
    private String password;
    private String nickname;

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }

    public User(Integer id, String username, String password, String nickname) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.nickname = nickname;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}
复制代码

(3)servlet

package com.atguigu.servlet;

import com.atguigu.user.User;
import com.atguigu.utils.JsonUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Chunsheng Zhang
 * 日期2021-05-21  10:06
 */
public class ServletDemo02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        // 1.由于请求体数据有可能很大,所以Servlet标准在设计API的时候要求我们通过输入流来读取
        BufferedReader reader = request.getReader();

        // 2.创建StringBuilder对象来累加存储从请求体中读取到的每一行
        StringBuilder builder = new StringBuilder();

        // 3.声明临时变量
        String bufferStr = null;

        // 4.循环读取
        while((bufferStr = reader.readLine()) != null) {
            builder.append(bufferStr);
        }

        // 5.关闭流
        reader.close();

        // 6.累加的结果就是整个请求体
        String requestBody = builder.toString();

        // 7.创建Gson对象用于解析JSON字符串
        Gson gson = new Gson();

        // 8.将JSON字符串还原为Java对象
        User user = gson.fromJson(requestBody, User.class);
        System.out.println("user = " + user);

        System.out.println("requestBody = " + requestBody);

        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("hello world");
    }
}
复制代码

此处可简化代码,在SpringMVC中提供@RequestBody,可以用来简化代码

服务器端返回JSON数据

1 前端
sendJsonBody(){
    axios({
        "method":"post",
        "url":"demo03"
    }).then(response => {
        console.log(response.data.nickname)
    })
}
复制代码
2 后端

(1)加入Gson包

(2)Servlet代码

package com.atguigu.servlet;

import com.atguigu.user.User;
import com.atguigu.utils.JsonUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Chunsheng Zhang
 * 日期2021-05-21  10:06
 */
public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
		//1. 创建user对象设置数据
		User user = new User(1,"aobama","123456","圣枪游侠");
        //2. 创建Gson对象用于将user对象转成json字符串
        Gson gson = new Gson();

        //3. 将user对象转成json字符串
        String jsonStr = gson.toJson(user);
        response.getWriter().write(jsonStr);
    }
}
复制代码
分类:
开发工具
标签:
分类:
开发工具
标签: