原生AJAX
HTML页面使用AJAX
-
创建对象
const xhr = new XMLHttpRequest()
-
初始化,设置请求方法和url,设置请求头类型
xhr.open(请求方式,url)
setRequestHeader(类型,字段)
-
发送(请求体)
xhr.send()
-
事件绑定,处理服务端返回结果
xhr.onreadystatechange = function(){ //判断状态与响应状态码 if(xhr.readyState === 4){ if(xhr.status >= 200 && xhr.status < 300){ 处理结果,返回到页面显示 } } }
+express框架的js文件
4.1. GET
Get.html
- url中?分隔 加参数名和值,多个参数之间用&
http://127.0.0.1:8000/server?a=100&b=200&c=300
- onreadystatechange
- on 相当于when,当。。。时候
- readystate是xhr对象中的属性,表示状态(该函数会被触发四次,该一个值触发一次,间隔触发0-1,1-2,2-3,3-4)
- 0:未初始化
- 1:open方法调用完毕
- 2:send方法调用完毕
- 3:服务器返回部分结果
- 4:服务器返回所有结果
- change 改变
- 状态为4,处理服务器返回结果
xhr.readystate === 4
- 判断响应状态码
- 200(2XX成功)
- 404 请求的资源(网页等)不存在
- 403 服务器理解请求客户端的请求,但拒绝执行此请求
- 401 请求要求用户的身份认证
- 500 内部服务器错误
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AJAX GET请求</title>
<style>
#result {
width: 360px;
height: 200px;
border: 2px solid #90EE90;
}
</style>
</head>
<body>
<!-- 210321 -->
<!-- 需求:点击按钮向服务端发送请求,结果返回客户端div中显示,页面不刷新 -->
<button>点击发送请求</button>
<div id="result"></div>
<script>
const btn = document.getElementsByTagName("button")[0];
const result = document.getElementById("result");
btn.onclick = function () {
// AJAX操作,四步
//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(open方法调用完毕)
2(send方法调用完毕)
3(服务端返回部分结果)
4(服务端返回所有结果)
触发四次,改一个值触发一次0-1(间隔是触发)*/
//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);//状态字符串
// console.log(xhr.getAllResponseHeaders());//所有响应头
// console.log(xhr.response);//响应体
//设置result的文本
result.innerHTML = xhr.response;
} else {
}
}
}
}
</script>
</body>
</html>
server.js
//1、引入express
const express = require('express');
//创建应用对象
const app = express();
//3、创建路由规则
//request 是对请求报文的封装
//response 时对响应报文的封装
app.get('/server', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应体
response.send('HELLO AJAX GET -2');
});
//4、监听端口启动服务
app.listen(8000, () => {
console.log("服务已经启动,8000端口监听中。。。。");
})
4.2. POST
post.html
- 设置请求头内容的类型
- 预定义
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
- 自定义
xhr.setRequestHeader('name', 'phy')
- 自定义,需在js文件中添加
response.setHeader('Access-Contorl-Allow-Headers', '*')
- 预定义
- send()中请求体的语法可以任意,常用json
xhr.send('a=100&b=200&c=300')
xhr.send('a:100&b:200&c:300')
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AJAX POST</title>
<style>
#result {
width: 360px;
height: 200px;
border: 2px solid #903;
}
</style>
</head>
<body>
<!-- 210321 -->
<!-- 需求:鼠标位于div上,发送请求 -->
<div id="result"></div>
<script>
//获取元素对象
const result = document.getElementById("result");
//绑定事件
result.addEventListener("mousemove", function () {
//1、创建对象
const xhr = new XMLHttpRequest();
//2、初始化,设置类型与URL
xhr.open('POST', 'http://127.0.0.1:8000/server');
//设置请求头内容的类型Content-Type,
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');//预定义
xhr.setRequestHeader('name', 'phy'); //可以自定义,自定义会报错,解决在.js文件中添加 response.setHeader('Access-Contorl-Allow-Headers','*');
//3、发送 请求体的语法可以任意与固定写法//最多、json
//xhr.send();
xhr.send('a=100&b=200&c=300');
// xhr.send('a:100&a:200&c:300');
//4、事件绑定
xhr.onreadystatechange = function () {
//判断
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
//处理服务端返回的结果
result.innerHTML = xhr.response;
}
}
}
})
</script>
</body>
</html>
server.js->post路由规则
//all可以接收任意类型的请求
app.all('/server', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Contorl-Allow-Headers', '*');
//设置响应体
response.send('HELLO AJAX POST');
});
4.3. JSON
json.html
- 当接收响应数据是字符串时
- ①:设置响应体数据类型,自动转json格式
xhr.responseType='json'
- ②:手动转换
let data = JSON.parse(xhr.response)
- ①:设置响应体数据类型,自动转json格式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSON响应</title>
<style>
#result {
width: 200px;
height: 100px;
border: 1px solid #FF69B4;
}
</style>
</head>
<body>
<!-- 200322 -->
<div id="result"></div>
<script>
window.onkeydown = function () {
const result = document.getElementById("result");
//发送请求
const xhr = new XMLHttpRequest();
//设置响应体数据的类型 //自动转换json格式
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) {
//服务器传递过来的数据是字符串,需要转换数据类型
//手动对数据转换 -->Object
//let data = JSON.parse(xhr.response);//服务器传过来的是字符串
//console.log(data);
//result.innerHTML = data.name;
//当接收响应体数据是字符串是,设置响应体数据的类型( xhr.responseType = 'json';) ,自动转换json格式
console.log(xhr.response);
result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
</html>
server.js
- 对象转字符串
JSON.stringfy()
app.all('/json-server', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Contorl-Allow-Headers', '*');
//响应一个数据
const data = {
name: 'phy'
};
//对对象进行字符串转换
let str = JSON.stringify(data);
//设置响应体 send方法只接收字符串与buffer(存储二进制数据)
response.send(str);
});
4.4. IE缓存问题
.html
- 设置每次请求的url不一致即可解决IE缓存问题
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>IE缓存问题</title>
<style>
#result {
width: 360px;
height: 200px;
border: 2px solid #258;
}
</style>
</head>
<body>
<!-- 210322 -->
<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();
//解决方法 每次生成的url不一样
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>
server.js
//针对IE缓存的
app.get('/ie', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应体
response.send('HELLO IE -5');
});
4.5. 请求超时与网络异常
.html
- 超时设置
xhr.timeout = 2000
- 超时回调
xhr.ontimeout
- 设置浏览器没有网
- chrome中network下选中online->offline
- 网络异常回调
xhr.onerror
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>请求超时与网络异常</title>
<style>
#result {
width: 360px;
height: 200px;
border: 2px solid #90b;
}
</style>
</head>
<body>
<!-- 210322 -->
<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.timeout = 2000;
//超时回调
xhr.ontimeout = function () {
alert("网络异常,请稍后重试!");
}
//网络异常回调 chrome中network下选中online->offline(设置浏览器没有网)
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>
server.js
//延时响应
app.all('/delay', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
setTimeout(() => {
response.send('延时响应');
}, 3000)
});
4.6. 取消请求与请求重复发送问题
.html
- 请求重复发送问题:相同的多个请求,会将前面的请求删掉
- 1、创建一个标识isSending = false,判断请求是否正在发送,是取消该请求,创建一个新的请求
- 2、创建的新请求,将标识赋值true
- 3、请求成功响应,标识赋值false
- 4、取消请求
xhr.abort()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<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 xhr = null;//不能用const,值一变就会报错
//标识变量
let isSending = false; //是否正在发送AJAX请求
btns[0].onclick = function () {
//判断标识变量
if (isSending)
//如果正在发送,则取消该请求,创建一个新的请求
xhr.abort();
xhr = new XMLHttpRequest();
//修改 标识变量的值
isSending = true;
xhr.open('GET', 'http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
//修改标识变量
isSending = false;
}
}
}
//取消abort
btns[1].onclick = function () {
xhr.abort();
}
//请求重复发送问题:相同的多个请求,将前面的请求删掉
</script>
</body>
</html>
server.js
//延时响应
app.all('/delay', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
setTimeout(() => {
response.send('延时响应');
}, 3000)
});