从前慢-ajax

Posted Java大世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从前慢-ajax相关的知识,希望对你有一定的参考价值。

前言

想要获取该该课程markdown笔记(脑图+笔记)。
搜索微信公众号-Java大世界。回复ajax,即可
获取笔记获取方式。

Ajax

1 Ajax 基础

1.1 什么是Ajax

Ajax 即Asynchronous javascript And XML
(异步 JavaScript 和 XML)。他不是一种新的编程语言,
而是一种通过异步实现网页的局部更新技术。

1.2 传统请求和异步请求

传统请求:   基于超级链接 地址栏 form表单 地
址栏 location.href 发起的请求全部是传统请求
特点: 请求之后,刷新整张页面
缺点: 由于刷新了整张页面,用户操作被中断,造成大量网络
流量的极大浪费。
异步请求: 基于ajax发起的请求都是异步请求
特点: 多个请求并行发生,请求之间互不影响,请求之后页面不
动,刷新页面的局部

1.3 传统网站中存在的问题

网速慢的情况下,页面加载时间长,用户只能等待
表单提交后,如果一项内容不合格,需要重新填写所有表单内容
页面跳转,重新加载页面,造成资源浪费,增加用户等待时间

1.4 Ajax 的应用场景

页面上拉加载更多数据
列表数据无刷新分页
表单项离开焦点数据验证
搜索框提示文字下拉列表

1.5 Ajax 运行原理

Ajax 相当于浏览器发送请求与接收响应的代理人,以实现
在不影响用户浏览页面的情况下,局部更新页面数据,从
而提高用户体验。

1.6 Ajax的核心对象

XMLHttpRequest 对象是一个javascript对象,存在
着浏览器差异。简称xhr对象

1.7 Ajax入门

1.  创建 Ajax 对象
var xhr = new XMLHttpRequest();
2. 告诉 Ajax 请求地址以及请求方式
xhr.open('get', 'http://www.example.com');
3. 发送请求
xhr.send();
4. 获取服务器端给与客户端的响应数据
xhr.onload = function () {
console.log(xhr.responseText);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open('get', 'http://localhost:3000/first');
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据
xhr.onload = function (){
console.log(xhr.responseText)
}
</script>
</body>
</html>

1.8 服务器端响应的数据格式

在真实的项目中,服务器端大多数情况下会以 JSON 对
象作为响应数据的格式。当客户端拿到响应数据时,要
将 JSON 数据和 HTML 字符串进行拼接,然后将拼接的结
果展示在页面中。
在 http 请求与响应的过程中,无论是请求参数还是
响应内容,如果是对象类型,最终都会被转换为对象字
符串进行传输。
JSON.parse() // 将 json 字符串转换为json对象

1.9 处理服务器端返回的JSON数据

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open('get', 'http://localhost:3000/responseData');
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据
xhr.onload = function (){
// console.log(typeof xhr.responseText)
// 将JSON字符串转换为JSON对象
var responseText = JSON.parse(xhr.responseText);
// 测试:在控制台输出处理结果
console.log(responseText)
// 将数据和html字符串进行拼接
var str = '<h2>'+ responseText.name +'</h2>';
// 将拼接的结果追加到页面中
document.body.innerHTML = str;
}
</script>
</body>
</html>

1.10 请求参数传递

传统网站表单提交
<form method="get" action="http://www.example.com">
<input type="text" name="username"/>
<input type="password" name="password">
</form>
<!– http://www.example.com?username=zhangsan&password=123456 -->

GET 请求方式
xhr.open('get', 'http://www.example.com?name=zhangsan&age=20');

POST 请求方式
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhr.send('name=zhangsan&age=20');

1.10.1 传递get请求参数

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p>
<input type="text" id="username">
</p>
<p>
<input type="text" id="age">
</p>
<p>
<input type="button" value="提交" id="btn">
</p>
<script type="text/javascript">
// 获取按钮元素
var btn = document.getElementById('btn');
// 获取姓名文本框
var username = document.getElementById('username');
// 获取年龄文本框
var age = document.getElementById('age');
// 为按钮添加点击事件
btn.onclick = function () {
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// 拼接请求参数
var params = 'username='+ nameValue +'&age=' + ageValue;
// 配置ajax对象
xhr.open('get', 'http://localhost:3000/get?'+params);
// 发送请求
xhr.send();
// 获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
}
</script>
</body>
</html>

1.10.2 传递post请求参数

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p>
<input type="text" id="username">
</p>
<p>
<input type="text" id="age">
</p>
<p>
<input type="button" value="提交" id="btn">
</p>
<script type="text/javascript">
// 获取按钮元素
var btn = document.getElementById('btn');
// 获取姓名文本框
var username = document.getElementById('username');
// 获取年龄文本框
var age = document.getElementById('age');
// 为按钮添加点击事件
btn.onclick = function () {
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// 拼接请求参数
var params = 'username='+ nameValue +'&age=' + ageValue;
// 配置ajax对象
xhr.open('post', 'http://localhost:3000/post');
// 设置请求参数格式的类型(post请求必须要设置)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 发送请求
xhr.send(params);
// 获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
}
</script>
</body>
</html>

1.10.3 向服务器端传递JSON格式的请求参数

请求参数的格式
1. application/x-www-form-urlencoded
name=zhangsan&age=20&sex=男
2. application/json
{name: 'zhangsan', age: '20', sex: '男'}
在请求头中指定 Content-Type 属性的值是 application/json,
告诉服务器端当前请求参数的格式是 json。
JSON.stringify() // 将json对象转换为json字符串
注意:get 请求是不能提交 json 对象数据格式的,传统网站的
表单提交也是不支持 json 对象数据格式的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open('post', 'http://localhost:3000/json');
// 通过请求头告诉服务器端客户端向服务器端传递的请求参数的格式是什么
xhr.setRequestHeader('Content-Type', 'application/json');
// JSON.stringify() 将json对象转换为json字符串
// 3.发送请求
xhr.send(JSON.stringify({name: 'lisi', age:50}));
// 4.获取服务器端响应到客户端的数据
xhr.onload = function (){
console.log(xhr.responseText)
}
</script>
</body>
</html>

1.11 Ajax 错误处理

1.   网络畅通,服务器端能接收到请求,服务器端返回的结果不是预期结果。
可以判断服务器端返回的状态码,分别进行处理。xhr.status 获取http状态码
2. 网络畅通,服务器端没有接收到请求,返回404状态码。
检查请求地址是否错误。
3. 网络畅通,服务器端能接收到请求,服务器端返回500状态码。
服务器端错误,找后端程序员进行沟通。
4. 网络中断,请求无法发送到服务器端。
会触发xhr对象下面的onerror事件,在onerror事件处理函数中对错误进行处理。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button id="btn">发送Ajax请求</button>
<script type="text/javascript">
var btn = document.getElementById('btn');

btn.onclick = function () {
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open('get', 'http://localhost:3000/error');
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据
xhr.onload = function (){
// xhr.status 获取http状态码
console.log(xhr.responseText);

if (xhr.status == 400) {
alert('请求出错')
}
}
// 当网络中断时会触发onerrr事件
xhr.onerror = function () {
alert('网络中断, 无法发送Ajax请求')
}
}

// Ajax状态码: 表示Ajax请求的过程状态 ajax对象返回的
// Http状态码: 表示请求的处理结果 是服务器端返回的
</script>
</body>
</html>

1.12 Ajax缓存

低版本 IE 浏览器的缓存问题
问题:在低版本的 IE 浏览器中,Ajax 请求有严重的缓存问题,即
在请求地址不发生变化的情况下,只有第一次请求会真正发送
到服务器端,后续的请求都会从浏览器的缓存中获取结果。
即使服务器端的数据更新了,客户端依然拿到的是缓存中的
旧数据。
解决方案:在请求地址的后面加请求参数,保证
每一次请求中的请求参数的值不相同。
xhr.open('get', 'http://www.example.com?t=' + Math.random());
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button id="btn">发送Ajax请求</button>
<script type="text/javascript">
var btn = document.getElementById('btn');

btn.onclick = function () {
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open('get', 'http://localhost:3000/cache?t=' + Math.random());
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据
xhr.onreadystatechange = function (){
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}

}
</script>
</body>
</html>

1.13 Ajax 异步编程

同步
一个人同一时间只能做一件事情,只有一件事情做完,才能做
另外一件事情。
落实到代码中,就是上一行代码执行完成后,才能执行下一
行代码,即代码逐行执行。
console.log('before');
console.log('after');

异步
一个人一件事情做了一半,转而去做其他事情,当其他事情做
完以后,再回过头来继续做之前未完成的事情。

落实到代码上,就是异步代码虽然需要花费时间去执行,但程
序不会等待异步代码执行完成后再继续执行后续代码,
而是直接执行后续代码,当后续代码执行完成后再回头看异
步代码是否返回结果,
如果已有返回结果,再调用事先准备好的回调函数处理异步
代码执行的结果。

console.log('before');
setTimeout(
() => { console.log('last');
}, 2000);
console.log('after');
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
// 1.创建ajax对象
var xhr = new XMLHttpRequest();
// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
// 1)请求方式 2)请求地址
xhr.open('get', 'http://localhost:3000/first', false);
// 3.发送请求
xhr.send();
// 4.获取服务器端响应到客户端的数据
xhr.onreadystatechange = function (){
if (xhr.readyState == 4) {
console.log('2')
console.log(xhr.responseText)
}

}

console.log('1');
</script>
</body>
</html>

1.14 ajax函数封装

问题:发送一次请求代码过多,发送多次请求代码冗余且重复。
解决方案:将请求代码封装到函数中,发请求时调用函数即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
function ajax (options) {
// 存储的是默认值
var defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function () {},
error: function () {}
};

// 使用options对象中的属性覆盖defaults对象中的属性
Object.assign(defaults, options); //options会覆盖defaults原有的属性

// 创建ajax对象
var xhr = new XMLHttpRequest();
// 拼接请求参数的变量
var params = '';
// 循环用户传递进来的对象格式参数
for (var attr in defaults.data) {
// 将参数转换为字符串格式
params += attr + '=' + defaults.data[attr] + '&';
}
// 将参数最后面的&截取掉
// 将截取的结果重新赋值给params变量
params = params.substr(0, params.length - 1);

// 判断请求方式
if (defaults.type == 'get') {
defaults.url = defaults.url + '?' + params;
}

/*
{
name: 'zhangsan',
age: 20
}

name=zhangsan&age=20

*/


// 配置ajax对象
xhr.open(defaults.type, defaults.url);
// 如果请求方式为post
if (defaults.type == 'post') {
// 用户希望的向服务器端` `传递的请求参数的类型
var contentType = defaults.header['Content-Type']
// 设置请求参数格式的类型
xhr.setRequestHeader('Content-Type', contentType);
// 判断用户希望的请求参数格式的类型
// 如果类型为json
if (contentType == 'application/json') {
// 向服务器端传递json数据格式的参数
xhr.send(JSON.stringify(defaults.data))
}else {
// 向服务器端传递普通类型的请求参数
xhr.send(params);
}

}else {
// 发送请求
xhr.send();
}
// 监听xhr对象下面的onload事件
// 当xhr对象接收完响应数据后触发
xhr.onload = function () {

// xhr.getResponseHeader()
// 获取响应头中的数据
var contentType = xhr.getResponseHeader('Content-Type');
// 服务器端返回的数据
var responseText = xhr.responseText;

// 如果响应类型中包含applicaition/json
if (contentType.includes('application/json')) {
// 将json字符串转换为json对象
responseText = JSON.parse(responseText)
}

// 当http状态码等于200的时候
if (xhr.status == 200) {
// 请求成功 调用处理成功情况的函数
defaults.success(responseText, xhr);
}else {
// 请求失败 调用处理失败情况的函数
defaults.error(responseText, xhr);
}
}
}

ajax({
type: 'post',
`// 请求地址
url: 'http://localhost:3000/responseData',
success: function (data) {
console.log('这里是success函数');
console.log(data)
}
})

/*
请求参数要考虑的问题

1.请求参数位置的问题

将请求参数传递到ajax函数内部, 在函数内部根据请求方式的不同将请求参数放置在不同的位置

get 放在请求地址的后面

post 放在send方法中

2.请求参数格式的问题

application/x-www-form-urlencoded

参数名称=参数值&参数名称=参数值

name=zhangsan&age=20

application/json

{name: 'zhangsan', age: 20}

1.传递对象数据类型对于函数的调用者更加友好
2.在函数内部对象数据类型转换为字符串数据类型更加方便

*/

</script>
</body>
</html>

2 编程扩展

2.1 模板引擎

作用:使用模板引擎提供的模板语法,可以将数据和 HTML 拼接起来。
官方地址:https://aui.github.io/art-template/zh-cn/index.html

安装
服务器端:npm install art-template --save
客户端:
官方地址:https://aui.github.io/art-template/zh-cn/index.html

2.1.1 客户端模板引擎使用步骤

使用步骤
1.下载 art-template 模板引擎库文件并在 HTML 页面中引入库文件
2.准备 art-template 模板
<script id="tpl" type="text/html">
<div class="box"> {{ username }} </div>
</script>
3. 告诉模板引擎将哪一个模板和哪个数据进行拼接
var html = template('tpl', {username: 'zhangsan', age: '20'});
document.getElementById('container').innerHTML = html;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<!-- 1. 将模板引擎的库文件引入到当前页面 -->
<script src="/js/template-web.js"></script>
</head>
<body>
<div id="container"></div>
<!-- 2.准备art-template模板 -->
<script type="text/html" id="tpl">
<h1>{{username}} {{age}}</h1>
</script>
<script type="text/javascript">
// 3.告诉模板引擎将那个数据和哪个模板进行拼接
// 1) 模板id 2)数据 对象类型
// 方法的返回值就是拼接好的html字符串
var html = template('tpl', {username: 'zhangsan', age: 30});
document.getElementById('container').innerHTML = html;
</script>
</body>
</html>

2.2 验证邮箱地址唯一性

获取文本框并为其添加离开焦点事件
离开焦点时,检测用户输入的邮箱地址是否符合规则
如果不符合规则,阻止程序向下执行并给出提示信息
向服务器端发送请求,检测邮箱地址是否被别人注册
根据服务器端返回值决定客户端显示何种提示信息
ajax.js
function ajax (options) {
// 默认值
var defaults = {
type: 'get',
url: '',
async: true,
data: {},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function () {},
error: function () {}
}
// 使用用户传递的参数替换默认值参数
Object.assign(defaults, options);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 参数拼接变量
var params = '';
// 循环参数
for (var attr in defaults.data) {
// 参数拼接
params += attr + '=' + defaults.data[attr] + '&';
// 去掉参数中最后一个&
params = params.substr(0, params.length-1)
}
// 如果请求方式为get
if (defaults.type == 'get') {
// 将参数拼接在url地址的后面
defaults.url += '?' + params;
}

// 配置ajax请求
xhr.open(defaults.type, defaults.url, defaults.async);
// 如果请求方式为post
if (defaults.type == 'post') {
// 设置请求头
xhr.setRequestHeader('Content-Type', defaults.header['Content-Type']);
// 如果想服务器端传递的参数类型为json
if (defaults.header['Content-Type'] == 'application/json') {
// 将json对象转换为json字符串
xhr.send(JSON.stringify(defaults.data))
}else {
// 发送请求
xhr.send(params);
}
} else {
xhr.send();
}
// 请求加载完成
xhr.onload = function () {
// 获取服务器端返回数据的类型
var contentType = xhr.getResponseHeader('content-type');
// 获取服务器端返回的响应数据
var responseText = xhr.responseText;
// 如果服务器端返回的数据是json数据类型
if (contentType.includes('application/json')) {
// 将json字符串转换为json对象
responseText = JSON.parse(responseText);
}
// 如果请求成功
if (xhr.status == 200) {
// 调用成功回调函数, 并且将服务器端返回的结果传递给成功回调函数
defaults.success(responseText, xhr);
} else {
// 调用失败回调函数并且将xhr对象传递给回调函数
defaults.error(responseText, xhr);
}
}
// 当网络中断时
xhr.onerror = function () {
// 调用失败回调函数并且将xhr对象传递给回调函数
defaults.error(xhr);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>验证邮箱地址是否已经注册</title>
<link rel="stylesheet" href="/assets/bootstrap/dist/css/bootstrap.min.css">
<style type="text/css">
p:not(:empty) {
padding: 15px;
}
.container {
padding-top: 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="form-group">
<label>邮箱地址</label>
<input type="email" class="form-control" placeholder="请输入邮箱地址" id="email">
</div>
<!-- 错误 bg-danger 正确 bg-success -->
<p id="info"></p>
</div>
<script src="/js/ajax.js"></script>
<script>
// 获取页面中的元素
var emailInp = document.getElementById('email');
var info = document.getElementById('info');

// 当文本框离开焦点以后
emailInp.onblur = function () {
// 获取用户输入的邮箱地址
var email = this.value;
// 验证邮箱地址的正则表达式
var reg = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/;
// 如果用户输入的邮箱地址不符合规则
if (!reg.test(email)) {
// 给出用户提示
info.innerHTML = '请输入符合规则的邮箱地址';
// 让提示信息显示为错误提示信息的样式
info.className = 'bg-danger';
// 阻止程序向下执行
return;
}

// 向服务器端发送请求
ajax({
type: 'get',
url: 'http://localhost:3000/verifyEmailAdress',
data: {
email: email
},
success: function (result) {
console.log(result);
info.innerHTML = result.message;
info.className = 'bg-success';
},
error: function (result) {
console.log(result)
info.innerHTML = result.message;
info.className = 'bg-danger';
}
});

}
</script>
</body>
</html>
该文章篇幅太大,想了解更多,点击阅读原文即可!
可能会出现微信没有相应,点击等待即可。


以上是关于从前慢-ajax的主要内容,如果未能解决你的问题,请参考以下文章

《从前慢》

从前慢-UML

从前的日子很慢

从前的日子很慢

从前慢-移动Web开发之响应式布局

从前慢-移动WEB开发之rem适配布局