第1章:原生AJAX
1.1 AJAX 简介
AJAX全称为Asynchronous JavaScript And XML,就是异步的JS和XML
通过AJAX可以在浏览器中向服务器发送异步请求。最大的优势:无刷新获取数据
AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的刷新方式。
1.2 XML简介
XML可扩展标记语法
XML被设计用来传输和存储数据(HTML–呈现数据)
XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,
全都是自定义标签,用来表示一些数据。
比如说我有一个学生数据
name="孙悟空;age=18;gender="男";
用XML表示:
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
</student>
现在已经被JSON取代了
用JSON表示:
{"name":"孙悟空","age":18;"gender":"男"}
1.3 AJAX的特点
1.3.1 AJAX的优点
- 可以无需刷新页面与服务器进行通信
- 允许你根据用户事件来更新部分页面内容
1.3.2 AJAX的缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO不友好
第二章: HTTP
HTTP(hypertext transport protocol) 协议【超文本传输协议】,协议详细规定了浏览器和万维网之间互相通信的规则
约定,规则
请求报文
重点是格式与参数
行 POST /s?ie=utf-8 HTTP/1.1
头 Host:atguigu.com
Cookie:name=guigu
Content-type:application/x-www-form-urlencoded
User-Agent:chrome 83
空行
体 username=admin&password=admin
响应报文
行 HTTP/1.1 200 OK
头 Content-Type:text/html;charset=utf-8
Content-length:2048
Content-encoding:gzip
空行
体 <html>
<head>
</head>
<body>
<h1>小明</h1>
</body>
</html>
- 404
- 403
- 401
- 500
- 200
让js文件修改后自动检测加载(注意需先安装node)
在VSCODE集成终端依次输入
npm install nodemon -g
(server.js是文件名)
nodemon sever.js
第三章:原生ajax的基本使用
GET
<!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>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.创建对象
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 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>
POST
<!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>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 () {
//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&:200&c:300');
// xhr.send('1234567');
//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 http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JSON</title>
<style>
#result {
width: 200px;
height: 100px;
border: solid 1px #89b;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
const xhr = new XMLHttpRequest();
//绑定键盘按下事件
window.onkeydown = function () {
//发送请求
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;
//2.自动转换
result.innerHTML = xhr.response.name;
}
}
};
};
</script>
</body>
</html>
IE缓存问题
<!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>IE缓存问题</title>
<style>
#result {
width: 200px;
height: 100px;
border: solid 1px #258;
}
</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();
xhr.open('GET', 'http://127.0.0.1:8000/ie?t=' + Date.now());
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 http-equiv="X-UA-Compatible" content="IE=edge" />
<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设置
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 http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>取消请求</title>
</head>
<body>
<button>点击发送</button>
<button>点击取消</button>
<script>
//获取元素对象
const btns = document.querySelectorAll('button');
let x = null;
btns[0].onclick = function () {
x = new XMLHttpRequest();
x.open('GET', 'http://127.0.0.1:8000/delay');
x.send();
};
//abort
btns[1].onclick = function () {
x.abort();
};
</script>
</body>
</html>
重复请求问题
<!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>重复请求问题</title>
</head>
<body>
<button>点击发送</button>
<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
btns[1].onclick = function () {
x.abort();
};
</script>
</body>
</html>
第四章:jQuery-AJAX
<!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>jQuery 发送 AJAX 请求</title>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu"
crossorigin="anonymous"
/>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.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">通用型方法ajax</button>
</div>
<script>
$('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: 300,
d: 400,
},
});
});
</script>
</body>
</html>
第五章:axios-AJAX
<!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>axios 发送 AJAX请求</title>
<script
crossorigin="anonymous"
src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.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: 'atguigu',
age: 20,
},
})
.then((value) => {
console.log(value);
});
};
btns[1].onclick = function () {
axios.post(
'/axios-server',
{
//请求体
username: 'admin',
password: 'admin',
},
{
//url
params: {
id: 200,
vip: 9,
},
//请求头参数
headers: {
height: 180,
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: 'admin',
},
}).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-AJAX
<!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>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: 'atguigu',
},
//请求体
body: 'username=admin&password=admin',
})
.then((response) => {
//return response.text();
return response.json();
})
.then((response) => {
console.log(response);
});
};
</script>
</body>
</html>
第七章:跨域
7.1 同源策略
同源策略最早由Netscape 公司提出,是浏览器的一种安全策略
同源:协议,域名,端口号 必须完全相同。
未被同源策略就是跨域
7.2 如何解决跨域
7.2.1 JSONP
-
JSONP是什么
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求
-
JSONP这么工作的?
在网页有一些标签天使具有跨域能力,比如:img link iframe script.
JSONP就是利用script标签的跨域能力来发送请求的
-
JSONP的使用
<!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>
<style>
#result {
width: 300px;
height: 100px;
border: solid 1px #089;
}
</style>
<script
crossorigin="anonymous"
src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/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) {
$('#result').html(`
名称:${data.name}<br>
房产:${data.family}`);
}
);
});
</script>
</body>
</html>
7.2.3 CORS
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
-
CORS是什么?
CORS,跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权访问哪些资源。
-
cors.html
<!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>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>
补充
注意:下面是全局的sever.js
//1.引入express
const { response } = require('express')
const express = require('express')
//2.创建应用对象
const app = express()
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
//设置响应体
response.send('HELLO AJAX')
});
//可以接收任意类型的请求
app.all('/server',(request,response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
response.setHeader('Access-Control-Allow-Headers','*')
//设置响应体
response.send('HELLO AJAX POST')
});
//JSON 响应
app.all('/json-server',(request,response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
response.setHeader('Access-Control-Allow-Headers','*')
//响应一个数据
const data={
name:'atguigu'
}
//对对象进行字符串转换
let str=JSON.stringify(data)
//设置响应体
response.send(str)
});
//针对IE缓存
app.get('/ie',(request,response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
//设置响应体
response.send('HELLO IE')
});
//延时响应
app.all('/delay',(request,response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
//设置响应体
setTimeout(()=>{
response.send('HELLO IE')
},3000)
});
//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))
});
//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))
});
//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))
});
app.all('/jsonp-server',(request,response)=>{
// response.send('console.log("hello liming")')
const data={
name:'李明'
}
//将数据转换为字符串
let str = JSON.stringify(data);
//返回结果
response.end(`handle(${str})`)
})
//用户名检测是否存在
app.all('/check-username',(request,response)=>{
// response.send('console.log("hello liming")')
const data={
exist:1,
msg:'用户名已经存在'
}
//将数据转换为字符串
let str = JSON.stringify(data);
//返回结果
response.end(`handle(${str})`)
})
app.all('/jquery-jsonp-server',(request,response)=>{
// response.send('console.log("hello liming")')
const data={
name:'李明',
family:['北京','上海','深圳']
}
//将数据转换为字符串
let str = JSON.stringify(data);
//接收callback 参数
let cb=request.query.callback;
//返回结果
response.end(`${cb}(${str})`)
})
app.all('/cors-server',(request,response)=>{
//设置响应头
response.setHeader("ACCESS-Control-Allow-Origin","*")
response.setHeader("ACCESS-Control-Allow-Headers","*")
response.setHeader("ACCESS-Control-Allow-Method","*")
response.send('hello CORS');
})
//4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务器已经启动,8000 端口监听中……")
})