AJAX
概述
AJAX ( Asynchronous JavaScript and XML ),异步的 JavaScript 和 XML。
简介
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
AJAX:
AJAX全称为 Asynchronous JavaScript And XML,就是异步的Js和XML。
通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
XML:
XML可扩展标记语肓。
XML被设计用来传输和存储数据。
XML 和 HTML类似,不同的是HTML中都是预定义标签,
而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。
AJAX的特点
优点
可以无需刷新页面而与服务器端进行吃后
运行你根据用户事件来更新邰分页面内容
缺点
浏览历史,不能回退
存在跨域问题(同源)
SEO(爬虫)不友好
HTTP
HTTP(hypertext transport protocol)协议『超文本传输协议』﹐
协议详细规定了浏览器和万维网服务器之间互相通信的规则。
请求报文:
行 POST /s?ie=utf-8 HTTP/1.1
头 Host: xxxx
Cookie: name=xxx
Content-type: application/x-www-form-urlencoded
空行
体 username=banq&xx=xxx
响应报文:
行 HTTP/1.1 200 OK
头 Content-ype: text/html;
charset=utf-8
Content-length: 2048
Content-encoding: gzip
空行
体 HTML结构
*/
</script>
</head>
<body>
</body>
</html>
express
// 1. 引入express
const { response } = require('express');
const express = require('express');
//2. 创建应用对象
const app = express();
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/',(request, response)=>{
//设置响应
response.send("HELLO EXPRESS");
});
//4. 监听端口启动服务
app.listen(8000, ()=>{
console.log("服务已经启动, 8000端口监听中....");
})
原生AJAX
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>
<style>
#result {
width: 200px;
height: 100px;
border: solid 1px #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. 创建AJAX对象
const xhr = new XMLHttpRequest();
//2. 设置请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&C=300');
//3. 发送
xhr.send();
//4. 事件绑定 处理服务端返回的结果
/*
on:when:当...时候
readystate: 是XHR对象中的一个属性,表示状态:
0(未初始化)
1(open方法调用完毕)
2(send方法调用完毕)
3(服务端返回部分结果)
4(服务端返回所有结果)
change:改变
*/
xhr.onreadystatechange = function () {
//作判断,是4(服务端返回了所有的结果)才处理数据
if (xhr.readyState === 4) {
//判断响应状态码:200 404 403 401 500
//2XX 都是成功
if (xhr.status >= 200 && xhr.status < 300) {
//处理服务端响应结果: 行 头 空行(咱不管) 体
//1. 处理响应行
// console.log(xhr.status);//状态码
// console.log(xhr.statusText);//状态字符串
// //2. 所有响应头
// console.log(xhr.getAllResponseHeaders());
// //3. 响应体
// console.log(xhr.response)
//设置result的文本
result.innerHTML = xhr.response;
} else {
}
}
}
// console.log('test');
}
</script>
</body>
</html>
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>
<style>
#result{
width: 200px;
height: 100px;
border: solid 1px #903;
}
</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','superLmk');
//3.发送
xhr.send('a=100&b=200&c:300');
// xhr.send('a:100&b:200&c:300');
// xhr.send('123456654123');
//4. 事件绑定
xhr.onreadystatechange = function () {
//判断
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
//处理服务端返回的结果
result.innerHTML = xhr.response;
}
}
}
}) </script>
</body>
</html>
JSON
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX JSON 响应</title>
<style>
#result{
width: 200px;
height: 100px;
border: solid 1px #89b;
}
</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;
//1. 手动对数据进行一个转换
// let data = JSON.parse(xhr.response);
// console.log(data);
// result.innerHTML = data.name;
//2. 自动转换:直接设置ajax响应数据类型
console.log(xhr.response);
result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
</html>
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 #90b;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
const btn = document.getElementsByTagName('button')[0];
const result = document.querySelector('#result');
btn.addEventListener('click', function () {
const xhr = new XMLHttpRequest();
//超时设置 2s 设置(2s内服务端不响应,就取消请求)
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function () {
alert('网络异常,请稍后重试!!');
}
//网络异常回调
xhr.onerror = function () {
alert('你的网络似乎出了一些问题!');
}
xhr.open('GET', 'http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
}
})
</script>
</body>
</html>
取消请求
<!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>
<button>点击取消</button>
<script>
//获取元素对象
const btns = document.querySelectorAll('button');
let x = null;
btns[0].onclick = function () {
// const x = new XMLHttpRequest();
x = new XMLHttpRequest();
x.open('GET', 'http://127.0.0.1:8000/delay');
x.send();
}
//abort (属于AJAX对象的一个方法)取消请求
//这里的 x 用 let 而不用const 好好思考一下
btns[1].onclick = function () {
x.abort();
}
</script>
</body>
</html>
重复请求问题
<!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 x = null;
//标识变量
let isSending = false;// 是否正在发送AJAX请求
btns[0].onclick = function () {
//判断标识变量
if (isSending) x.abort();//如果该请求正在发送,则取消该请求,创建一个新的请求
x = new XMLHttpRequest();
//修改 标识变量的值
isSending = true;
x.open('GET', 'http://127.0.0.1:8000/delay');
x.send();
x.onreadystatechange = function () {
if (x.readyState === 4) {
//修改标识变量
//这里不用判断响应状态码,因为这个请求可能是失败的请求
isSending = false;
}
}
}
//abort (属于AJAX对象的一个方法)取消请求
//这里的 x 用 let 而不用const 好好思考一下
btns[1].onclick = function () {
x.abort();
}
</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>axios 发送AJAX请求</title>
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.js"></script>
</head>
<body>
<button>GET</button>
<button>POST</button>
<button>AJAX</button>
<script>
const btns = document.querySelectorAll('button');
//配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[0].onclick = function () {
//GET 请求
axios.get('/axios-server', {
//url参数
params: {
id: 100,
vip: 7
},
//请求头信息
headers: {
name: 'Nliver',
age: 20
}
//Axios是基于Promise作的数据处理
}).then(value => {
console.log(value)
})
}
btns[1].onclick = function () {
axios.post('/axios-server', {
//请求体
username: 'admin',
password: '123456'
}, {
//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:200
},
//请求体参数
data: {
username: 'admin',
password: '123456'
}
}).then(response=>{
console.log(response);
//响应状态码
console.log(response.status);
//响应状态字符串
console.log(response.statusText);
//响应头信息
console.log(response.headers);
//响应体
console.log(response.data);
})
}
</script>
</body>
</html>
fetch
<!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: 'Nliver'
},
//请求体
body: 'username=admin&password=admin'
}).then(response => {
// console.log(response);
// return response.text();
return response.json();
}).then(response => {
console.log(response);
})
}
</script>
</body>
</html>
AJAX跨域问题
同源策略
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
<h1>Nliver</h1>
<button>点击获取用户数据</button>
<script>
const btn = document.querySelector('button');
btn.onclick = function () {
const x = new XMLHttpRequest();
//这里因为是满足同源策略的,所以url可以简写
x.open("GET", '/data');
//发送
x.send();
//
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
console.log(x.response);
}
}
}
}
</script>
</body>
</html>
const { response } = require('express');
const express = require('express');
const app = express();
app.get('/home', (request, response) => {
//响应一个页面
response.sendFile(__dirname + '/index.html');
});
app.get('/data', (request, response) => {
//响应一个页面
response.send('用户数据');
});
app.listen(9000, () => {
console.log("服务已经启动...");
})
JSONP
<!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: 300px;
height: 100px;
border: solid 1px #78a;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
//处理数据
function handle(data) {
//获取 result 元素
const result = document.getElementById('result');
result.innerHTML = data.name;
}
</script>
<!-- <script src="./js/app.js"></script> -->
<!-- <script src="http://127.0.0.1:5500/%E4%BB%A3%E7%A0%81/7-AJAX%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/2-JSONP/js/app.js"></script> -->
<script src="http://127.0.0.1:8000/jsonp-server"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原生JSONP 实践案例</title>
</head>
<body>
用户名: <input type="text" id="username">
<p></p>
<script>
//获取input元素
const input = document.querySelector('input');
const p = document.querySelector('p');
//声明 handle 函数
function handle(data) {
//修改边框颜色
input.style.border = "solid 1px #f00";
//修改 p 标签的提交文本
p.innerHTML = data.msg;
}
//绑定事件
input.onblur = function () {
//获取用户的输入值
let username = this.value;
//向服务端发送请求 检测用户名是否存在
//1. 创建 script 标签
const script = document.createElement('script');
//2. 设置 script 标签的src属性
script.src = 'http://127.0.0.1:8000/check-username';
//3. 将 script 插入到文档中
document.body.appendChild(script);
}
</script>
</body>
</html>
JQuery-JSONP
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery-jsonp</title>
<style>
#result {
width: 300px;
height: 100px;
border: solid 1px #089;
}
</style>
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<button>点击发送 jsonp 请求</button>
<div id="result">
</div>
<script>
$('button').eq(0).click(function(){
$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function(data){
// console.log(data);
$('#result').html(`
名称: ${data.name}<br />
校区: ${data.city}
`)
})
});
</script>
</body>
</html>
CORS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CORS 跨域资源共享</title>
<style>
#result {
width: 200px;
height: 100px;
border: solid 1px #90b;
}
</style>
</head>
<body>
<button>发送请求</button>
<div id="result"></div>
<script>
const btn = document.querySelector('button');
btn.onclick = function () {
//1. 创建对象
const x = new XMLHttpRequest();
//2. 初始化设置
x.open('GET', "http://127.0.0.1:8000/cors-server");
//3. 发送
x.send();
//4. 绑定事件
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
//输出响应体
console.log(x.response);
}
}
}
}
</script>
</body>
</html>