AJAX
说明:前五节是AJAX的一个基本介绍以及练习的工具。第六节介绍AJAX的发送请求方法以及遇到问题的处理
一、什么是AJAX
AJAX = 异步 JavaScript 和 XML,是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
优点:1.无需刷新页面与服务器进行通信。2.允许根据用户事件来更新部分页面内容。
缺点:1.没有浏览历史,不能回退。2.存在跨域问题(同源)。3.SEO不友好(不能爬虫)。.
二、什么是XML
XML是可拓展标记语言,用于传输和存储数据,XML与HTML类似,但是XML中没有预定义标签(div,ul,p标签等),而是使用自定义标签。HTML用于呈现数据
如:存储一个用户数据
name:"小红";age:18;sex:"女"
用XML表示:
<users>
<name>小红</name>
<age>18</age>
<sex>女</sex>
</users>
传递方式:服务端将XML通过字符串的形式传递到客户端,客户端再用JS进行处理
目前被json取代
三、JSON
JSON相对于XML来讲,JSON对数据的描述性比XML差,但JSON数据体积小,传递速度更快,
与JavaScript交互更加方便,更容易解析处理,更好数据交互。
如:存储一个用户数据
{"name":"小红","age":18,"sex":"女"}
四、AJAX请求基本操作
五、Express框架
为了方便练习,搞一个服务端,express框架是基于node环境下的一个框架
1.安装
npm i express
2.创建服务端 server.js 文件
//1.引入 express
const express = require('express');
const { request } = require('express');
//2.创建应用对象
const app = express();
//3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/',(request,response)=>{
//设置响应
response.send('HELLO EXPRESS');
});
// 4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000 端口监听中.... ");
})
3.启动方式:node server.js
如果不想重复启动可以安装nodemon自动重启工具
npm install -g nodemon
启动方式:
nodemon server.js
之后ctrl s 就可以了
六、AJAX发送请求
1、POST、GET请求
POST
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX POST 请求</title>
<!-- 需求:将鼠标放入框内时发送POST请求,将返回的数据显示到框内 -->
<style>
#result{
width: 200px;
height: 100px;
border: 1px solid #f55;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
// 获取元素对象
const result = document.getElementById('result');
// 绑定事件
result.addEventListener('mouseover',function(){
// console.log('test');
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置类型与URL
xhr.open('POST','http://127.0.0.1:8000/server');
// 设置请求头
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','atguigu')//自定义的请求头
// 3.发送,设置请求体
xhr.send('a=100&b=200&c=300');
// xhr.send('a:100&b:200&c:300');
// xhr.send('123456789');
//4.事件绑定
xhr.onreadystatechange = function(){
//判断
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
//处理服务端返回的结果
result.innerHTML = xhr.response;
}
}
}
});
</script>
</body>
</html>
GET
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX GET 请求</title>
<!-- 需求:点击发送请求,将服务端返回的数据渲染到result中 -->
<style>
#result{
width: 200px;
height: 100px;
border: 1px solid #90b;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
//获取button元素
const btn = document.getElementsByTagName('button')[0];
const result = document.getElementById('result');
//绑定事件
btn.onclick = function(){
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置请求方法和url
// 设置URL方式:在末尾加 ?a=100&b=200&c=300
xhr.open('GET','http://127.0.0.1:8000/server?a=100&b=200&c=300');
// 3.发送
xhr.send();
// 4.事件绑定 处理服务器返回的结果
// onreadystatechange 表示
// on when 当...的时候
// readyState 是xhr对象中的属性,表示状态0 1 2 3 4
// change 改变
xhr.onreadystatechange = function(){
//判断(服务端返回了所有的结果)
if(xhr.readyState === 4){
// 判断响应状态码 200 404 403 401 500
// 2xx 代表成功
if(xhr.status >= 200 && xhr.status < 300){
//处理结果 行 头 空行 体
// 响应
// console.log(xhr.status,' 状态码');//状态码
// console.log(xhr.statusText,' 状态字符串');//状态字符串
// console.log(xhr.getAllResponseHeaders(),' 所有响应头');//所有响应头
// console.log(xhr.response,' 响应体');//响应体
//设置 result 的文本
result.innerHTML = xhr.response;
}
}
}
}
</script>
</body>
</html>
2、AJAX对服务端响应JSON数据格式的转换
解决方法:
1.手动转换
let data = JSON.parse(xhr.response);
console.log(data);
result.innerHTML = data.name;
2.自动转换(先设置响应体数据类型)
xhr.responseType = 'json';
result.innerHTML = xhr.response.name;
server.js
//响应JSON数据
app.all('/json-server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*');
//响应一个数据
const data = {
name: 'atshsd',
};
//对对象进行字符串转换
let str = JSON.stringify(data);
// 设置响应体
response.send(str);
});
AJAX
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON响应</title>
<!-- 需求:当鼠标按下或按下enter键,向服务端发送请求,将返回的结果显示到div盒子上
-->
<style>
#result{
width: 200px;
height: 100px;
border: 1px solid #f66;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
const result = document.getElementById('result');
//绑定键盘按下事件
window.onkeydown = function(){
// console.log('test')
// 发送请求
const xhr = new XMLHttpRequest();
//设置响应体数据的类型
xhr.responseType = 'json';
//初始化
xhr.open('GET','http://127.0.0.1:8000/json-server');
//发送
xhr.send();
//事件绑定 处理服务器返回的结果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >=200 && xhr.status <300){
// console.log(xhr.response);
// result.innerHTML = xhr.response;
// 手动对数据转换
// let data = JSON.parse(xhr.response);
// console.log(data);
// result.innerHTML = data.name;
//自动转换:先设置响应体数据的类型
// console.log(xhr.response);
result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
</html>
3、解决IE缓存问题
当服务端数据发生改变时,在浏览器中刷新,IE浏览器不会同步更新服务端的数据
解决方法:在初始化请求方法中加入Date.now() 方法
// 2.初始化设置请求方法
xhr.open('GET','http://127.0.0.1:8000/ie?t='+Date.now());
4、请求超时和网络异常处理
当服务端数据长时间没有响应时,AJAX做处理
解决方法:1.timeout设置一个响应时间。2.ontimeout超时回调。3.onerror网络异常回调。
server.js
// 延时响应
app.get('/delay', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
setTimeout(() => {
// 设置响应体
response.send('延时响应');
},3000);
});
AJAX
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>请求超时与网络异常</title>
<style>
#result {
width: 200px;
height: 100px;
border: solid 1px #900;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
// 获取button元素
const btn = document.getElementsByTagName('button')[0];
const result = document.getElementById('result');
//绑定事件
btn.onclick = function () {
// 1.创建对象
const xhr = new XMLHttpRequest();
// 超时设置 2s 设置
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function () {
alert('网络异常,请稍后再试!!');
};
//网络异常回调
xhr.onerror = function () {
alert('你的网络似乎出现了问题!');
};
// 2.初始化,设置请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/delay');
// 3.发送请求
xhr.send();
// 4.事件绑定 对服务端返回数据做处理
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
};
};
btn.addEventListener;
</script>
</body>
</html>
5、取消请求
点击取消时,AJAX取消像服务端发送请求
解决方法:通过添加abort()方法
AJAX
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX取消请求</title>
<!-- 需求:通过点击取消按钮,取消AJAX发送请求 -->
</head>
<body>
<button>点击发送</button>
<button>点击取消</button>
<script>
const btns = document.querySelectorAll('button');
let xhr = null;
// 发送请求
btns[0].onclick = function(){
xhr = new XMLHttpRequest();
xhr.open('GET','http://127.0.0.1:8000/delay');
xhr.send();
}
// 取消请求 abort()方法
btns[1].onclick = function(){
xhr.abort();
}
</script>
</body>
</html>
6、解决重复请求问题
当用户疯狂点击某一个按钮向服务器发送请求时,会给服务器造成压力,所以需要将最新请求之前的请求全部取消
解决方法:创建一个值为false的标识变量。当发送请求时该变量为true;请求结束后,状态值为4,则该变量为false。再判断当变量为false时执行abort()方法。
AJAX
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX重复发送请求</title>
<!-- 需求:用户在频繁点击发送按钮请求服务器时,将最新以外的请求全部取消掉 -->
</head>
<body>
<button>点击发送</button>
<script>
const btns = document.querySelectorAll('button');
let xhr = null;
//创建一个标识变量
let isSending = false
// 发送请求
btns[0].onclick = function(){
if(isSending)xhr.abort();//如果isSending为false,则取消该请求
xhr = new XMLHttpRequest();
// 发送请求时标识变量值为true
isSending = true;
xhr.open('GET','http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
// 请求结束后标识变量值为false
isSending =false
}
};
}
</script>
</body>
</html>
7、jQuery方法发送AJAX请求
包含GET,POST,通用三种方法:
server.js
//jQuery 服务
app.all('/jquery-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers','*');
const data = {name:'小红'};
response.send(JSON.stringify(data));
});
AJAX
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery 发送 AJAX请求</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">jQuery发送AJAX请求</h2>
<button class="btn btn-primary">GET</button>
<button class="btn btn-danger">POST</button>
<button class="btn btn-info">通用方法</button>
</div>
<script>
/*
第一个参数:给谁发(http://127.0.0.1:8000/jquery-server)
第二个参数:发送什么,是一个对象,{key:value}形式
第三个参数:回调函数,其中的data是响应体
第四个参数:响应体类型(常用的为json)
*/
$('button').eq(0).click(function(){
$.get('http://127.0.0.1:8000/jquery-server',{a:100,b:200},function(data){
console.log(data);
},'json')
})
$('button').eq(1).click(function(){
$.post('http://127.0.0.1:8000/jquery-server',{a:100,b:200},function(data){
console.log(data);
})
})
$('button').eq(2).click(function(){
$.ajax({
//url
url:'http://127.0.0.1:8000/jquery-server',
//参数
data:{a:100,b:200},
//请求类型
type:'GET',
//响应体结果
dataType:'json',
//成功的回调
success:function(data){
console.log(data);
},
//超时时间
timeout:2000,
//失败的回调
error:function(){
console.log('出错');
},
//头信息
headers:{
c:200,
d:300
}
})
})
</script>
</body>
</html>
8、axios发送AJAX请求
也包含GET、POST、通用方法
server.js
//axios 服务
app.all('/axios-server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*');
// 设置响应体
const data = {name:'你好'};
response.send(JSON.stringify(data));
});
ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>axios 发送 AJAX请求</title>
<script
crossorigin="anonymous"
src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0-0/axios.js"
></script>
</head>
<body>
<button>GET</button>
<button>POST</button>
<button>通用方式</button>
<script>
const btns = document.querySelectorAll('button');
//配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
//GET 方法
btns[0].onclick = function () {
//请求类型
axios
.get('/axios-server', {
//url 参数
params: {
id: 100,
vip: 7,
},
//请求头信息
headers: {
name: 'sdasd',
age: 20,
},
})
.then((res) => {
console.log(res);
});
};
//POST方法
btns[1].onclick = function () {
//请求类型
axios.post(
'/axios-server',
{
username: 'admin',
password: 'admin',
},
//url
{
params: {
id: 200,
vip: 9,
},
//请求头参数
headers: {
height: 100,
weight: 180,
},
}
);
};
// 通用方法
btns[2].onclick = function () {
axios({
// 请求类型
method: 'POST',
// url
url: '/axios-server',
//url参数
params: {
vip: 10,
level: 30,
},
//头信息
headers: {
a: 100,
b: 100,
},
// 请求体参数
data: {
username: 'admin',
password: 'admin',
},
}).then((res) => {
// 响应结果
console.log(res);
// 响应状态码
console.log(res.status);
//响应状态字符串
console.log(res.statusText);
// 响应头信息
console.log(res.headers);
//响应体
console.log(res.data);
});
};
</script>
</body>
</html>
9、fetch函数发送AJAX请求
server.js
//fetch 服务
app.all('/fetch-server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*');
// 设置响应体
const data = {name:'你好'};
response.send(JSON.stringify(data));
});
ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>fetch 发送 AJAX请求</title>
</head>
<body>
<button>AJAX请求</button>
<script>
const btn = document.querySelector('button');
btn.onclick = function(){
fetch('http://127.0.0.1:8000/fetch-server?vip=10',{
//请求方法
method:'POST',
//请求头
headers:{
name:'sadadf'
},
//请求体
body:'username=admin&password=admin'
}).then(res=>{
// return res.text();
return res.json();
}).then(res=>{
console.log(res);
})
}
</script>
</body>
</html>
以上对AJAX的总结是在b站上学习后进行的个人总结,有不足的地方希望大佬们多多指正 ,视频地址在下方 :)
链接: link