大家一起加油,我喜欢分专栏将知识打碎成一份一份小知识点,一篇文章只说一个知识点,因此每篇文章篇幅较短,希望大家不要介意。如有需要可以查看专栏看看是否有该文章中涉及到的知识点进行讲解的文章,如果大家觉得有帮助,希望大家三连支持一下。 |
文章结构
AJAX
AJAX是什么?
anync javascript and xml
异步js和xml
浏览器向服务器发送异步请求,无刷新获取数据
XML是什么?
与HTML类似,但是没有预定义的标签,标签全都是自己定义的,都是成对的标签
<student>
<name>zhangsan</name>
<age>20</age>
</student>
但是现在已经被JSON替代了,JSON格式更加的简洁
javascript{"name":"zhangsan","age":20}
AJAX的特点
AJAX的优点
1、无需刷新页面与服务器端进行通信
2、更新部分页面的内容
AJAX的缺点
1、没有浏览历史,不能回退
2、存在跨域问题
3、seo对爬虫不友好,爬虫爬取不到页面的内容
使用express起一个本地的后端,用来测试AJAX和Jquery以及fetch发送请求
const express = require('express');
const app = express();
app.get('/server', (req, res) => {
// 设置响应头,允许跨域
res.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
res.send('Hello Ajax GET ');
});
app.post('/server', (req, res) => {
// 设置响应头,允许跨域
res.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
res.send('Hello Ajax POST ');
})
// 不管是什么请求都可以响应
app.all('/server-json', (req, res) => {
// 设置响应头,允许跨域
res.setHeader('Access-Control-Allow-Origin', '*');
let person = {
name: 'zhangsan',
age: 18
}
person = JSON.stringify(person);
// 设置响应体
res.send(person);
})
// ie缓存
app.all('/server-ie', (req, res) => {
// 设置响应头,允许跨域
res.setHeader('Access-Control-Allow-Origin', '*');
let person = {
name: 'zhangsan',
age: 19
}
person = JSON.stringify(person);
// 设置响应体
res.send(person);
})
// 网络延迟-手动取消请求-节流
app.all('/delay', (req, res) => {
// 设置响应头,允许跨域
res.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
setTimeout(function() {
res.send('网络延迟');
},3000);
})
// ajax发送请求
app.all('/ajax', (req, res) => {
// 设置响应头,允许跨域
res.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头,可以自定义头部信息
res.setHeader('Access-Control-Allow-Headers', '*');
// 设置响应体
let message = {mag:'请求成功'}
res.send(JSON.stringify(message));
})
// fetch发送请求
app.all('/fetch', (req, res) => {
// 设置响应头,允许跨域
res.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头,可以自定义头部信息
res.setHeader('Access-Control-Allow-Headers', '*');
// 设置响应体
let message = {mag:'请求成功'}
res.send(JSON.stringify(message));
})
app.listen(80, () => {
console.log('服务器启动成功');
});
使用AJAX发送请求
发送GET请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
#result {
width: 200px;
height: 200px;
border: 1px solid black;
}
</style>
</head>
<body>
<button type="button">点击发送请求</button>
<div id="result"></div>
<script type="text/javascript">
const btn = document.querySelector('button');
const result = document.querySelector('#result');
btn.onclick = function(){
// 发送ajax请求
// 1、创建对象
const xhr = new XMLHttpRequest();
// 请求参数
let params = null;
// 2、初始化
xhr.open('GET','http://localhost/server?'+params);
// 3、发送
xhr.send();
// 4、事件绑定onload不兼容ie6
// on when 当...的时候
// readystate 是xhr对象的属性,表示状态0 1 2 3 4
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.responseText;
}else {
}
}
}
}
</script>
</body>
</html>
发送POST请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
#result {
width: 200px;
height: 200px;
border: 1px solid black;
}
</style>
</head>
<body>
<button type="button">点击发送请求</button>
<div id="result"></div>
<script type="text/javascript">
const btn = document.querySelector('button');
const result = document.querySelector('#result');
btn.onclick = function(){
// 发送ajax请求
// 1、创建对象
const xhr = new XMLHttpRequest();
// 请求参数
let params = null;
// 2、初始化
xhr.open('POST','http://localhost/server');
// 设置请求头,必须在open和send之间,设置请求参数的类型
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
// 3、发送
xhr.send(params);
// 4、事件绑定onload不兼容ie6
// on when 当...的时候
// readystate 是xhr对象的属性,表示状态0 1 2 3 4
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.responseText;
}else {
}
}
}
}
</script>
</body>
</html>
接收服务器端发送的JSON格式数据
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
#result {
width: 200px;
height: 200px;
border: 1px solid black;
}
</style>
</head>
<body>
<button type="button">点击发送请求</button>
<div id="result"></div>
<script type="text/javascript">
const btn = document.querySelector('button');
const result = document.querySelector('#result');
btn.onclick = function() {
// 发送ajax请求
// 1、创建对象
const xhr = new XMLHttpRequest();
// 请求参数
let params = null;
// 2、初始化
xhr.open('GET', 'http://localhost/server-json?' + params);
// 设置响应体数据类型
xhr.responseType = 'json';
// 3、发送
xhr.send();
// 4、事件绑定onload不兼容ie6
// on when 当...的时候
// readystate 是xhr对象的属性,表示状态0 1 2 3 4
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);//响应体
// 接收服务器返回的JSON数据
// // 手动转换
// let person = JSON.parse(xhr.responseText);
// 自动转换,设置返回数据的格式即可xhr.responseType = 'json';
// 设置result的文本,字符串
// result.innerHTML = person.name;
result.innerHTML = xhr.response.age + "-" + xhr.response.name;
} else {
}
}
}
}
</script>
</body>
</html>
ie浏览器的缓存问题,ajax数据更新,ie记录原有数据
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
#result {
width: 200px;
height: 200px;
border: 1px solid black;
}
</style>
</head>
<body>
<button type="button">点击发送请求</button>
<div id="result"></div>
<script type="text/javascript">
var btn = document.getElementsByTagName('button')[0];
var result = document.getElementById('#result');
btn.onclick = function() {
// 发送ajax请求
// 1、创建对象
var xhr = new XMLHttpRequest();
// 2、初始化
// 给请求加一个时间戳,这样再次发送ajax请求时,ie会认为不是同一个请求,会重新发送请求,从而接收到服务器端可能已经发生改变的数据
xhr.open('GET', 'http://localhost/server-ie?t=' + new Date());
// 设置响应体数据类型
xhr.responseType = 'json';
// 3、发送
xhr.send();
// 4、事件绑定onload不兼容ie6
// on when 当...的时候
// readystate 是xhr对象的属性,表示状态0 1 2 3 4
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);//响应体
// 接收服务器返回的JSON数据
// // 手动转换
// let person = JSON.parse(xhr.responseText);
// 自动转换,设置返回数据的格式即可xhr.responseType = 'json';
// 设置result的文本,字符串
// result.innerHTML = person.name;
console.log(xhr.response);
} else {
}
}
}
}
</script>
</body>
</html>
Ajax请求超时,网络异常
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
#result {
width: 200px;
height: 200px;
border: 1px solid black;
}
</style>
</head>
<body>
<button type="button">点击发送请求</button>
<div id="result"></div>
<script type="text/javascript">
const btn = document.getElementsByTagName('button')[0];
const result = document.getElementById('#result');
btn.onclick = function(){
// 发送ajax请求
// 1、创建对象
const xhr = new XMLHttpRequest();
// 2、初始化
// 超时设置,浏览器network中请求会取消
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function(){
alert('网络延迟,稍后重试');
}
// 网络异常回调,用谷歌浏览器的Network中的网络状态改为Offline
xhr.onerror = function(){
alert('断网了');
}
xhr.open('GET','http://localhost/delay');
// 3、发送
xhr.send();
// 4、事件绑定onload不兼容ie6
// on when 当...的时候
// readystate 是xhr对象的属性,表示状态0 1 2 3 4
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);//响应体
// 接收服务器返回的JSON数据
// // 手动转换
// let person = JSON.parse(xhr.responseText);
// 自动转换,设置返回数据的格式即可xhr.responseType = 'json';
// 设置result的文本,字符串
// result.innerHTML = xhr.response;
console.log(xhr.response);
}else {
}
}
}
}
</script>
</body>
</html>
手动取消请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<button type="button">点击发送请求</button>
<button type="button">点击取消请求</button>
<script type="text/javascript">
const btn = document.querySelectorAll('button');
let xhr = null;
btn[0].onclick = function(){
xhr = new XMLHttpRequest();
xhr.open('GET','http://localhost/delay');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
console.log(111);
}
}
}
}
btn[1].onclick = function(){
xhr.abort();
}
</script>
</body>
</html>
节流-避免重复发送ajax请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<button type="button">点击发送请求</button>
<button type="button">点击取消请求</button>
<script type="text/javascript">
const btn = document.querySelectorAll('button');
let xhr = null;
let flag = false;
btn[0].onclick = function(){
if(flag) xhr.abort();
flag = true;
xhr = new XMLHttpRequest();
xhr.open('GET','http://localhost/delay');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
flag = false;
if(xhr.status >= 200 && xhr.status < 300){
console.log(111);
}
}
}
}
btn[1].onclick = function(){
xhr.abort();
}
</script>
</body>
</html>
使用jquery发送请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<script src="./jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<button type="button">点击发送GET请求</button>
<button type="button">点击发送POST请求</button>
<button type="button">通用性方法</button>
<script type="text/javascript">
$('button').eq(0).click(function(){
$.get('http://localhost/jquery',{a:10,b:20},function(data){
// data就是响应体
console.log(data);
},'json')
})
$('button').eq(1).click(function(){
$.post('http://localhost/jquery',{a:10,b:20},function(data){
console.log(data);
})
})
$('button').eq(2).click(function(){
$.ajax({
// url
url: "http://127.0.0.1/jquery",
// 请求参数
data: {a:10,b:20},
// 请求类型
type: "GET",
// 响应体格式
dataType: "json",
// 成功的回调
success: function(data){
console.log(data);
},
// 超时时间,超过这个时间还没有接收到服务器端的响应就会请求失败
timeout: 2000,
// 失败的回调,可以将路径指向delay模拟失败
error: function(){
console.log('出错了');
},
// 头部信息,记得设置响应头可以自定义头部信息
headers: {
a:300,
b:100
}
})
})
</script>
</body>
</html>
使用fetch发送请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<button type="button">fetch发送请求</button>
<script type="text/javascript">
const btn = document.querySelector('button');
btn.onclick = function(){
fetch('http://localhost/fetch?id=1',{
method: 'POST',
headers: {
id:1,
vip:7
},
// body可以发送params格式,json格式
body: 'username=admin&password=123456'
}).then(response => {
// return response.text()
return response.json()
}).then(value => console.log(value))
}
</script>
</body>
</html>
使用json-server模拟后端来测试axios发送请求
json-server npm源地址
db.json
{
"posts": [{
"id": 1,
"title": "json-server",
"author": "typicode"
},
{
"title": "今天天气不错, 还挺风和日丽的",
"author": "张三",
"id": 2
},
{
"title": "今天天气不错, 还挺风和日丽的",
"author": "张三",
"id": 3
}
],
"comments": [{
"id": 1,
"body": "some comment",
"postId": 1
},
{
"body": "喜大普奔",
"postId": 2,
"id": 2
}
],
"profile": {
"name": "typicode"
}
}
使用axios发送请求
axios的基本使用
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>axios基本使用</title>
<link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">基本使用</h2>
<button class="btn btn-primary"> 发送GET请求 --请求id为2的数据 </button>
<button class="btn btn-warning" > 发送POST请求 --添加一条数据 </button>
<button class="btn btn-success"> 发送PUT请求 --将id为3的author改为李四 </button>
<button class="btn btn-danger"> 发送DELETE请求 --将id为3的数据删除 </button>
</div>
<script>
//获取按钮
const btns = document.querySelectorAll('button');
//第一个
btns[0].onclick = function(){
//发送 AJAX 请求
axios({
//请求类型
method: 'GET',
//URL
url: 'http://localhost:3000/posts/2',
}).then(response => {
console.log(response);
});
}
//添加一篇新的文章
btns[1].onclick = function(){
//发送 AJAX 请求
axios({
//请求类型
method: 'POST',
//URL
url: 'http://localhost:3000/posts',
//设置请求体
data: {
title: "今天天气不错, 还挺风和日丽的",
author: "张三"
}
}).then(response => {
console.log(response);
});
}
//更新数据
btns[2].onclick = function(){
//发送 AJAX 请求
axios({
//请求类型
method: 'PUT',
//URL
url: 'http://localhost:3000/posts/3',
//设置请求体
data: {
title: "今天天气不错, 还挺风和日丽的",
author: "李四"
}
}).then(response => {
console.log(response);
});
}
//删除数据
btns[3].onclick = function(){
//发送 AJAX 请求
axios({
//请求类型
method: 'delete',
//URL
url: 'http://localhost:3000/posts/3',
}).then(response => {
console.log(response);
});
}
</script>
</body>
</html>
axios的其它使用
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
axios的默认配置
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>axios默认配置</title>
<link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">基本使用</h2>
<button class="btn btn-primary"> 发送请求 </button>
</div>
<script>
//获取按钮
const btns = document.querySelectorAll('button');
//默认配置
axios.defaults.method = 'GET'; //设置默认的请求类型为 GET
axios.defaults.baseURL = 'http://localhost:3000'; //设置基础 URL
axios.defaults.params = {
id: 1
};
// axios请求超过时间阀之后自动取消请求
axios.defaults.timeout = 3000; //
btns[0].onclick = function() {
axios({
url: '/posts'
}).then(response => {
console.log(response);
})
}
</script>
</body>
</html>
axios创建实例对象
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>axios实例对象</title>
<link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<script>
//获取按钮
const btns = document.querySelectorAll('button');
//创建实例对象 /getJoke
const duanzi = axios.create({
baseURL: 'http://localhost:3000',
timeout: 2000
});
const onather = axios.create({
baseURL: 'http://localhost:3000',
timeout: 2000
});
duanzi({
url: '/comments',
}).then(response => {
console.log(response);
});
onather.get('/profile').then(response => {
console.log(response.data)
})
</script>
</body>
</html>
axios拦截器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拦截器</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<script>
// Promise
// 设置请求拦截器 config 配置对象
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 1号');
//修改 config 中的参数
config.params = {a:100};
return config;
}, function (error) {
console.log('请求拦截器 失败 - 1号');
return Promise.reject(error);
});
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 2号');
//修改 config 中的参数
config.timeout = 2000;
return config;
}, function (error) {
console.log('请求拦截器 失败 - 2号');
return Promise.reject(error);
});
// 设置响应拦截器
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 1号');
return response.data;
// return response;
}, function (error) {
console.log('响应拦截器 失败 1号')
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 2号')
return response;
}, function (error) {
console.log('响应拦截器 失败 2号')
return Promise.reject(error);
});
//发送请求
axios({
method: 'GET',
url: 'http://localhost:3000/posts'
}).then(response => {
console.log('自定义回调处理成功的结果');
console.log(response);
});
</script>
</body>
</html>
axios取消请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>取消请求</title>
<link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">axios取消请求</h2>
<button class="btn btn-primary"> 发送请求 </button>
<button class="btn btn-warning"> 取消请求 </button>
</div>
<script>
//获取按钮
const btns = document.querySelectorAll('button');
//2.声明全局变量
let cancel = null;
//发送请求
btns[0].onclick = function() {
//检测上一次的请求是否已经完成
if (cancel !== null) {
//取消上一次的请求
cancel();
}
axios({
method: 'GET',
// 使用之前的express来测试
url: 'http://localhost/delay',
//1. 添加配置对象的属性
cancelToken: new axios.CancelToken(function(c) {
//3. 将 c 的值赋值给 cancel
cancel = c;
})
}).then(response => {
console.log(response);
//将 cancel 的值初始化
cancel = null;
})
}
//绑定第二个事件取消请求
btns[1].onclick = function() {
cancel();
}
</script>
</body>
</html>
结束啦!