一 Ajax
1.1 Ajax是什么
Ajax (读音: [ˈeɪˌdʒæks] )(Asynchronous JavaScript And XML)全称是异步的 Javascript 和 XML ,我们可以先不纠结名字的意思。你只要知道Ajax是一种快速访问后台得到想要数据的技术,可做到在不重新加载整个界面的情况下,完成网页的局部刷新操作。
其实很常见,比如我们的博学谷网站注册页面,如下:
当我们输入手机号完毕,在输入框失去焦点事件触发时,就偷偷的访问了博学谷后台,查看是否存在该手机号,然后后台把查询结果又返回到浏览器中,局部的刷新数据,让你知道手机号已经存在。
怎么判断没有做整个网页的数据刷新呢?输入框的数据是还在的,如果我们刷新下网页,数据都没了。
1.2 同步和异步
Ajax可做到在不重新加载整个界面的情况下,做到网页的局部刷新操作,这个操作其实就是一种异步操作。我们来具体分析下什么是同步,异步。
异步操作
浏览器发送一个请求,不需要等待服务端响应返回,随时可以再发送下一个请求,即不需要等待,浏览器与服务器是并行工作的
同步操作
浏览器发起请求的时候,服务器收到请求,在处理该请求的过程中有一定时间,在服务器返回结果给浏览器之前,浏览器只能等待。收到服务器响应后,浏览器才能做下一步操作,浏览器与服务器是串行工作的。
同步和异步各有千秋
- 同步的执行效率会比较低,耗费时间,但有利于我们对流程进行控制,避免很多不可掌控的意外情况;
- 异步的执行效率高,节省时间,但是会占用更多的资源,也不利于我们对进程进行控制
1.3 Ajax的应用场景
网页局部的数据请求刷新操作都可以使用Ajax技术。
比如我们上面提到的注册表单的用户名异步校验,搜索引擎内容补全推荐 等
二 axios使用
2.1 axios介绍
axios 读音[æk'si:əʊz]
是对ajax技术的一种封装,类似一个框架一样。简单来说: ajax技术实现了网页的局部数据刷新,axios实现了对ajax的封装。
写前端项目时,若要使用axios,首先就要先导入axios js文件,就好像Java项目导入的jar包。
2.2 axios使用
1)使用步骤
- 引入axios核心js文件。
- 调用axios对象的方法来发起异步请求。
- 调用axios对象的方法来处理响应的数据。
2)环境搭建
我们现在写的是前端代码,要用Ajax技术访问后台。我们需要先模拟一个后台出来使用,资料(或附件)中有一个java后台程序backend.jar
,我们先运行起来使用。
backend.zip 该附件下载后需要解压取出里面的backend.jar 文件
操作步骤:
- 在backend.jar 所在的目录,打开CMD命令行工具。(CMD目录要对)
- 执行命令
java -jar backend.jar
启动后台程序。输入命令按回车执行,看到效果如下,表示执行成功:
若出现如下情况表示端口冲突,启动失败 这是vs code插件 Preview on Web Server 的服务器端口使用了8080,我们需要找到该插件然后更改其端口。操作如下: 设置页面如下:
- 打开浏览器输入地址:http://127.0.0.1:8080/axiosDemo01Servlet?username=Jack&password=123456
如果能够看到如下效果,说明后台启动成功,后面的Ajax就有后台可以请求了。
3)axios常用方法
axios 对象的方法
get( 请求地址含请求参数 ) 发起异步的get请求 post( 请求地址 , 请求参数) 发起异步的get请求
then( 回调函数 ) 响应成功回调的函数 catch( 回调函数 ) 响应异常回调的函数(可以不写) finally( 回调函数 ) 无论如何,最终都会回调的函数(可以不写)
4)axios实现get请求
:::tips
我们下面要实现,用axios请求后台数据案例,首先我需要有个网址(url),如下:
http://127.0.0.1:8080/axiosDemo01Servlet?username=张三丰&password=123456
以上网址叫做url(Uniform Resource Locator 全球资源定位器)包含两部分内容:地址,参数
- 地址:http://127.0.0.1:8080/axiosDemo01Servlet
- 参数:username=张三丰&password=123456 (就是要提交到后台的键值对,多个参数用 & 拼接)
在get请求中,参数是拼接在地址后面的,格式: 地址?参数 :::
核心代码示例:
<!--
1. 引入axios核心js文件 (ajax请求库)
2. 调用axios对象的方法来发起异步请求
3. 调用axios对象的方法来处理响应的数据
-->
<script src="js/axios-0.18.0.js"></script>
<script>
//请求地址
let url = "http://127.0.0.1:8080/axiosDemo01Servlet?username=张三丰&password=123456"
//使用axios请求后台数据
axios
.get(url)
.then(function (response) {
//正常响应回调函数,浏览器收到后台的数据响应时会调用这个函数。
//数据,通过response传给我们。我们先简单输出到控制台查看下
console.log(response);
})
.catch(function (error) {
//错误时回调的函数
console.log(error);
})
.finally(function () {
//操作结束时无论如何都会回调的函数
console.log("无论如何都会调用的函数");
})
</script>
浏览器控制台看到结果如下:
resonse具体数据如下,我们后面学习Json对象时说。
{
"data": "axios实现ajax异步get请求,username=张三丰",
"status": 200,
"statusText": "",
"headers": {
"content-length": "49",
"content-type": "application/json;charset=utf-8"
},
"config": {
"transformRequest": {},
"transformResponse": {},
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"headers": {
"Accept": "application/json, text/plain, */*"
},
"method": "get",
"url": "http://127.0.0.1:8080/axiosDemo01Servlet?username=张三丰&password=123456"
},
"request": {}
}
注意:一定要先启动后台程序,否则出现如下错误:Network Error
5)anxios实现post请求
在post请求中,参数不是拼接到地址后面,需要单独传,如下:
我们可以把get请求用的地址分成两部分:
let **url** = "http://127.0.0.1:8080/axiosDemo01Servlet"
let **param**="username=张三丰&password=123456"
axios.post(**url**,**param**)<br /> .then(...)<br /> .catch(...)<br /> .finally(...)
<!--
1. 引入axios核心js文件 (ajax请求库)
2. 调用axios对象的方法来发起异步请求
3. 调用axios对象的方法来处理响应的数据
-->
<script src="js/axios-0.18.0.js"></script>
<script>
//请求地址
let url = "http://127.0.0.1:8080/axiosDemo01Servlet"
let param="username=张三丰&password=123456"
//使用axios请求后台数据
axios
.post(url,param)
.then(function (response) {
//正常响应回调函数,浏览器收到后台的数据响应时会调用这个函数。
//数据,通过response传给我们。我们先简单输出到控制台查看下
console.log(response);
})
.catch(function (error) {
//错误时回调的函数
console.log(error);
})
.finally(function () {
//操作结束时无论如何都会回调的函数
console.log("无论如何都会调用的函数");
})
</script>
</html>
2.3 检查用户名是否已注册
注册过程中,我们不希望用户重复注册,通常会异步检查用户名是否存在,如下:
需求:
:::danger
我们来模拟实现在注册过程中,用户名异步检查是否存在的功能。
先准备测试环境(参考2.2章节中环境搭建步骤),已知在后台已经存在一个用户名 岩岩。实现,若输入岩岩用户名提示用户名已存在。其他就提示恭喜!用户名可用
检查用户名地址需要用post进行请求:
- 地 址:http://localhost:8080/registerServlet
- 参数名:username
注意,给后台参数要使用键值对,例如检查Jack用户名。参数应该是:username=Jack
:::
参考代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="width: 250px; margin: auto;padding: 50px;border: 2px deeppink dashed">
<form action="#">
新用户注册<br>
<input type="text" name="username" placeholder="请输入用户名" id="username" size="20"><br>
<span id="nameSpan"></span> <br>
注册密码:<br>
<input type="password" name="password" placeholder="请输入密码"> <br><br>
<button>提交</button>
</form>
</div>
</body>
<!-- 导入axios类库 -->
<script type="text/javascript" src="js/axios-0.18.0.js"></script>
<script type="text/javascript">
//1.使用js获取用户名输入框的标签对象并给其绑定一个离焦事件onblur
document.getElementById('username').onblur = function () {
//2.事件触发时,获取用户名
//let username = document.getElementById("username").value
//this 就是当前绑定的对象
let username = this.value;
if (username == '') {
document.getElementById('nameSpan').innerHTML = "<font color='red'>用户名不能为空</font>"
return
}
//3.axios提交数据到后台查询是否存在
//地址
let url = "http://localhost:8080/registerServlet"
//参数
let param = "username=" + username
axios.post(url, param)
.then(resp => {
// 4.在axios的回调函数中处理后台响应的数据
let result = resp.data;
//5.根据响应的结果进行判断
if (result == false) {
//6.用户名存在,不能注册,提示用户名已经存在
document.getElementById('nameSpan').innerHTML = "<font color='red'>用户名存在,重新输入</font>"
} else {
//7.用户名不存在,可以注册,提示可以注册
document.getElementById('nameSpan').innerHTML = "<font color='green'>恭喜!用户名可用</font>"
}
});
//💝试试把上面的回调函数改造为箭头函数
};
</script>
</html>
三 JSON
3.1 JSON是什么
JSON(读作“Jason”)是JavaScript对象。使用JSON表示法时,对象可以方便地转换为字符串来进行存储和转换(比如在不同程序或网络之间)。
json是目前 前后端数据交互的主要格式之一
我们上面的Ajax案例中请求返回的数据就是json数据。
3.2 JSON定义和使用
1)语法格式
JSON数据的表示方式是由一系列键值对组成,键和值之间由冒号分隔,键值对之间以逗号分隔,如下所示:
"name1":"value1", "name2":"value2", "name3":"value3"
最终这些键值对用花括号包围起来,构成表示数据的JSON对象:
let jsonObject = {
"name1":"value1",
"name2":"value2",
"name3":"value3"
}
比如,我们创建表示用户,商品的对象。
let user ={
"username":"后羿",
"age":23,
"sex":"男"
}
let product = {
name:"小米10",
desc:"1亿像素的手机小王子",
aa:{
a:"b",
c:"d"
}
bb:["Hello","World"]
}
注意:
- 其中name必须是string类型
json在js中,name的双引号可以省略,建议加双引号
value必须是以下数据类型之一:
字符串,数字,对象(JSON 对象),数组,布尔,Null
- JSON 中的字符串必须用双引号包围。(单引号不行!主要是涉及到后期在后端java代码中操作)
可以和Java一样,去定义属性,方法:
/*
Java:
class Student{
//成员变量
String name = "张三";
int age=18;
//成员方法
public void study(){
}
}
*/
let stu ={
"name":"张三",
"age":18,
study:(name)=>{
alert(name+"好好学习,天天向上")
}
}
console.log(stu.name+","+stu.age)
stu.study("huji")
2)JSON的使用
- 指定键名获取值:对象名.键名。
- 指定键名赋值: 对象名.键名=新值
- 可以用for循环:迭代JSON里面的键值对数据 ```json let obj1 = { “name”: “张三”, “age”: 18, “height”: 180 }
//对象输出到控制台 console.log(obj1)
//1)指定键名获取值:象名.键名。 console.log(obj1.name) //张三
//2)指定键名赋值: 象名.键名=新值 obj1.name = “张三丰”
//3)可以用for循环:迭代JSON里面的键值对数据
for (const key in obj1) {
const element = obj1[key];
console.log(${key}:${element}
)
}
:::success
执行效果如下<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22810121/1653448001946-a335a940-5cc3-4b1e-88c9-f969ac6961b9.png#clientId=u7330acd5-87fb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=184&id=u711d6b0e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=292&originWidth=752&originalType=binary&ratio=1&rotation=0&showTitle=false&size=28733&status=done&style=shadow&taskId=u028cf7c5-6ae9-46ef-90a1-7ef847b261f&title=&width=473.0666809082031)
:::
<a name="Wy3RZ"></a>
### 3)常见的JSON存在形式
```json
//1. 对象类型
{name:value , name:value, ....}
//2. 数组类型
[
{name:value,name:value},
{name:value,name:value},
{name:value,name:value}
]
//3. 复杂对象
{
name:value,
wives:[{name:value},{},{}],
son:{name:value}
}
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
<script type="text/javascript">
/*1.对象类型 :{key:value,key:value,...} */
let obj1 = { "name": "昌昌", "age": 18, "height": 180 }
//对象输出到控制台
console.log(obj1)
//指定键名获取值:象名.键名。
console.log(obj1.name) //昌昌
//指定键名赋值: 象名.键名=新值
obj1.name = "昌老师"
//可以用for循环:迭代JSON里面的键值对数据
for (const key in obj1) {
const element = obj1[key];
console.log(`${key}:${element}`)
}
/* 2.数组类型
[{key:value,key:value,...},{key:value,key:value,...},{key:value,key:value,...},...]
*/
let obj2 = [
{ "name": "昌昌", "age": 18, "height": 180 },
{ "name": "轩轩", "age": 19, "height": 180 },
{ "name": "艺艺", "age": 20, "height": 180 }
]
/*3.复杂对象 3:
{key:value,key:[key:value,key1:value1,...],key:value,...}
*/
let obj3 = {
"name": "轩轩",
"score": [{ "数学": 99.9 }, { "英语": 100 }, { "语文": 100 }]
}
console.log(obj3)
</script>
</html>
四 好友列表案例(ajax和json综合)
运行后台backend.jar(参考2.2章节中:环境搭建)
:::success
需求:向后台发送请求,获取好友列表并显示到页面中,如下
:::
分析:
1)一直后台提供功能接口地址
http://localhost:8080/axiosJsonDemo01Servlet
返回json数据如下:
{
"flag": true,
"message": "查询好友列表成功",
"valueData": [
{
"age": 18,
"id": "001",
"name": "张三"
},
{
"age": 19,
"id": "002",
"name": "李四"
},
{
"age": 20,
"id": "003",
"name": "王五"
}
]
}
2)将json数据解析出来,填充到HTML表格中
代码参考:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>ajax和json综合</h1>
<!--
获取好友列表
-->
<input type="button" value="响应数据是json字符串" onclick="method01()"> <br>
<hr>
<h3>好友列表</h3>
<!--存放查询好友的结果信息-->
<div id="messageDiv" style="color:green"></div>
<table width="500px" cellspacing="0px" cellpadding="5px" border="1px" id="myTable">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
<!--<tr>
<td></td>
<td></td>
<td></td>
</tr>-->
</table>
</body>
<!--导入axios库-->
<script type="text/javascript" src="js/axios-0.18.0.js"></script>
<script type="text/javascript">
/*
需求:向后台发送请求,获取好友列表并显示到页面中
说明:后台的url地址: "http://localhost:8080/axiosJsonDemo01Servlet"
*/
function method01() {
//向后台发送请求
axios.post("http://localhost:8080/axiosJsonDemo01Servlet")
.then(resp => {
//1.接收后端响应的Result对象
let obj = resp.data;
console.log(obj);
//2.判断是否成功
if (obj.flag) {
//查询成功
document.getElementById('messageDiv').innerHTML = obj.message;
//取出数组
let arr = obj.valueData;
//遍历数组取出每个json对象
//定义变量保存每个对象的数据的tr内容
let content = "";
for (let friend of arr) {//friend 表示每个json对象===={age: 18, id: '001', name: '张三'}
//这里书写是+= 累加
content += `
<tr>
<td>${friend.id}</td>
<td>${friend.name}</td>
<td>${friend.age}</td>
</tr>
`
}
//3.获取table标签对象
let oTable = document.getElementById('myTable');
//4.将获取的数据即content放到table标签的文本中 appendChild
oTable.innerHTML += content;//这里使用+=,这样就不会覆盖原来的表头tr
} else {
//查询失败
document.getElementById('messageDiv').innerHTML = obj.message;
}
});
}
</script>
</html>