AJAX

AJAX

AJAX全称为Asynchronous JavaScript And XML,就是异步的 JS 和 XML。通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势: 无刷新获取数据。AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

XML简介
XML 可扩展标记语言。

XML 被设计用来传输和存储数据。

XML 和 HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。

1
2
3
4
5
6
7
8
9
比如说我有一个学生数据:
name = "孙悟空",age = 18; gender = "男";

用XML表示:
<student>
<name>孙悟空</name>
<age>18</age>
<gender></gender>
</student>

现在已经被JSON取代了。

用JSON表示:

1
{"name":"孙悟空","age":18,"gender":"男"}

AJAX特点

优点:

  1. 可以无需刷新页面而与服务器端进行通信。
  2. 允许你根据用户事件来更新部分页面内容。

缺点:

  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)
  3. SEO不友好,(SEO意思: 是搜索引擎优化)

HTTP协议请求与响应的结构

参见:网络协议 - Hexo (mk310.github.io)

express框架

使用express框架之前要安装node.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# npm init --yes 初始化
# npm i express 安装express npm如何安装在5博客里面有写。

# 1.引入express
const express = require('express');
# 2.创建应用对象
const app = express();

# 3.创建路由规则
# request 是对请求报文的封装
# response 是对响应报文的封装
app.get('/',(request,response)=>{
response.send("Hello,express!");
});

# 4.监听端口启动服务
app.listen(8080,()=>{
console.log("服务已经启动,8080端口监听中.....");
})

# node 文件名.js 启动测试 访问127.0.0.1:8080

GET请求(原生)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!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.创建对象
const xhr = new XMLHttpRequest();
//2.初始化,设置请求方法和url
xhr.open('GET','http://127.0.0.1:8080/server');
//3.发送
xhr.send();
//4.事件绑定 处理服务端返回的结果
// readystate 是xhr对象中的属性,表示状态0,1,2,3,4
/*
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
*/
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 1.引入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');
});

//4.监听端口启动服务
app.listen(8080,()=>{
console.log("服务已经启动,8080端口监听中.....");
})

POST请求(原生)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!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(){
//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');
//3.发送
xhr.send();
//4.事件绑定
xhr.onreadystatechange = function(){
//判断
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
//处理服务端返回的结果
result.innerHTML = xhr.response;
}
}
}

});
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 1.引入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.post('/server',(request,response)=>{
//设置响应头
response.setHeader('Access-Control-Allow-Origin','*');

//设置响应体
response.send('HELLO AJAX');
});

//4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中.....");
})

服务器响应JSON数据(原生)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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 result = document.getElementById('result');
//绑定键盘按下事件
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){
result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 1.引入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.post('/server',(request,response)=>{
// //设置响应头
// response.setHeader('Access-Control-Allow-Origin','*');

// //设置响应体
// response.send('HELLO AJAX');
// });
app.get('/json-server',(request,response)=>{
//设置响应头
response.setHeader('Access-Control-Allow-Origin','*');

//响应一个数据
const data = {
name: 'atguigu'
}
//对对象进行字符串转换
let str = JSON.stringify(data);
//设置响应体
response.send(data);
});

//4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中.....");
})

IE缓存问题(原生)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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?time='+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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 1.引入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.post('/server',(request,response)=>{
// //设置响应头
// response.setHeader('Access-Control-Allow-Origin','*');

// //设置响应体
// response.send('HELLO AJAX');
// });
app.get('/json-server',(request,response)=>{
//设置响应头
response.setHeader('Access-Control-Allow-Origin','*');

//响应一个数据
const data = {
name: 'atguigu'
}
//对对象进行字符串转换
let str = JSON.stringify(data);
//设置响应体
response.send(data);
});
app.get('/ie',(request,response)=>{
//设置响应头
response.setHeader('Access-Control-Allow-Origin','*');

//设置响应体
response.send('HELLO IE');
});

//4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中.....");
})

请求异常与网络超时(原生)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!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 #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();
//超时设置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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 1.引入express
const express = require('express');
// 2.创建应用对象
const app = express();

// 3.创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/server',(request,response)=>{
});
//json
app.get('/json-server',(request,response)=>{
});
//ie缓存
app.get('/ie',(request,response)=>{
});
//延迟响应
app.get('/delay',(request,response)=>{
//设置响应头
response.setHeader('Access-Control-Allow-Origin','*');
//定时器
setTimeout(()=>{
//设置响应体
response.send('延时响应');
},3000)

});
//4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中.....");
})

取消发送(原生)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!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>
<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();
}
btns[1].onclick = function(){
//abort 中止
x.abort();
}
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 1.引入express
const express = require('express');
// 2.创建应用对象
const app = express();

// 3.创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/server',(request,response)=>{
});
//json
app.get('/json-server',(request,response)=>{
});
//ie缓存
app.get('/ie',(request,response)=>{
});
//延迟响应
app.get('/delay',(request,response)=>{
//设置响应头
response.setHeader('Access-Control-Allow-Origin','*');
//定时器
setTimeout(()=>{
//设置响应体
response.send('延时响应');
},3000)

});
//4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中.....");
})

请求重复发送(原生)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!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>
<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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 1.引入express
const express = require('express');
// 2.创建应用对象
const app = express();

// 3.创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/server',(request,response)=>{
});
//json
app.get('/json-server',(request,response)=>{
});
//ie缓存
app.get('/ie',(request,response)=>{
});
//延迟响应
app.get('/delay',(request,response)=>{
//设置响应头
response.setHeader('Access-Control-Allow-Origin','*');
//定时器
setTimeout(()=>{
//设置响应体
response.send('延时响应');
},3000)

});
//4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中.....");
})