AJAX技术

异步js,axios

1. 原生ajax

1.1. ajax简介

全称:Asynchronous JavaScript And XML (异步JavaScript和XML)

在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式就是ajax

通过ajax可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据

ajax不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式

1.2. XML简介

Extensible Makeup Language,可拓展标记语言

被用来传输和存储数据

和html不同,HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示数据

1
2
3
4
5
<student>
<name>name</name>
<age>18</age>
<gender>female</gender>
</student>

现在已经被json取代

1
2
3
4
5
{
"name":'name',
"age":18,
"gender":"female"
}

2. HTTP协议

Hypertext transport protocol 超文本传输协议

协议规定了浏览器和万维网服务器之间互相通信的规则

2.1. 请求报文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 请求行
请求方式 url HTTP/1.1

# 请求头
access-control-allow-origin: *
cache-control: max-age=31536000
content-encoding: gzip
content-md5: NZucY8s7pDOEspleVpmmPw==
content-type: application/x-javascript
server: AliyunOSS

# 空行

# 请求体
post方式下存在提交表单:name=name&&password=123

2.2. 响应报文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 响应行
HTTP/1.1 200 OK

# 响应头
access-control-allow-origin: *
cache-control: max-age=31536000
content-encoding: gzip
content-md5: NZucY8s7pDOEspleVpmmPw==
content-type: application/x-javascript
server: AliyunOSS

# 空行

# 响应体
<html>
<head></head>
<body></body>
</html>

3. 基本操作

3.1. 核心对象

XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的。

3.2. AJAX 请求状态

xhr.readyState 可以用来查看请求当前的状态

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState

0: 表示 XMLHttpRequest 实例已经生成,但是 open()方法还没有被调用

1: 表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP请求的头信息

2: 表示 send()方法已经执行,并且头信息和状态码已经收到

3: 表示正在接收服务器传来的 body 部分的数据

4: 表示服务器数据已经完全接收,或者本次接收已经失败了

3.3. 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
// 1. 创建对象
const xhr = new XMLHttpRequest();

// 2. 初始化,设置请求方法和url
xhr.open("get","http://127.0.0.1:3700/show/all");

// 3. 发送
xhr.send();

// 4. 事件绑定,处理服务器返回的结果
// readystate是xhr对象中的特性,表示状态
// 0: 请求未初始化
// 1: 服务器连接已建立
// 2: 请求已接收 接收到了响应头
// 3: 请求处理中 正在下载响应体
// 4: 请求已完成,且响应已就绪
xhr.onreadystatechange = function(e){
// console.log(e);
if(xhr.readyState == 4){
// console.log(xhr);
// 状态码 200
console.log(xhr.status);
// 状态字符串 OK
console.log(xhr.statusText);
// 响应头
// content-length: 4326
// content-type: application/json; charset=utf-8
console.log(xhr.getAllResponseHeaders());
// 响应体
console.log(xhr.response);
}
}

3.4. post

1
2
3
4
5
6
7
8
9
10
// 1. 创建对象
const xhr = new XMLHttpRequest();

// 2. 初始化,设置请求方法和url
xhr.open("post","http://127.0.0.1:3700/show/all");

// 3. 发送+参数
// xhr.send("uname=a&&pwd=123");
// xhr.send("uname:a&&pwd:123");
// xhr.send("123");

3.5. 设置请求头

1
xhr.setRequestHeader("Content-Type","application/xxx-form-urlencoded");

需要允许自定义请求头

1
response.setHeader("Access-Control-Allow-Header","*");

此时会预先发送OPTIONS 请求

1
2
3
4
5
6
7
8
app.all("/show",(request,response)=>{
//允许跨域
response.setHeader("Access-Control-Allow-Origin","*");
//响应头
response.setHeader("Access-Control-Allow-Header","*");
//响应体
response.send("Hello Ajax");
});

4. 响应JSON数据

4.1. 方法一:JSON.parse()

1
2
3
4
5
6
7
8
9
10
// 后台 nodejs
const data={
name: 'uname'
}
let str = JSON.stringify(data);


// 前端
let data = JSON.parse(xhr.reponse);
document.getElementById("div").innerHTML = data.name;

4.2. 方法二:xhr.responseText

1
2
3
// 设置响应体数据类型
xhr.responseText="json";
let data = xhr.reponse.name;

5. IE缓存问题

IE对于同一个路由访问请求到的数据进行缓存,再次请求得到的是缓存数据

解决:时间戳

1
xhr.open("get","http://127.0.0.1/show/all?time="+Date.now());

6. 请求超时与异常处理

1
2
3
4
5
6
7
8
9
10
11
12
// 超时2s处理
xhr.timeout=2000;

// 超时回调
xhr.ontimeout = function(){
alert("超时");
}

// 网络异常
xhr.onerror = function(){
alert("网络异常");
}

7. 取消请求

1
xhr.abort();

8. 重复访问路由

设置互斥锁

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
let xhr = null;
let isSending = false;

document.querySelectorAll("button")[0].onclick = function(){
if(isSending){
// 丢弃原有请求
xhr.abort();
}

// 1. 创建对象
xhr = new XMLHttpRequest();

// 2. 初始化,设置请求方法和url
xhr.open("get","http://127.0.0.1:3700/show/all");

// 3. 发送
xhr.send();

// 4. 事件绑定,处理服务器返回的结果
xhr.onreadystatechange = function(e){

if(xhr.readyState == 4){
isSending = true;
}
}
}

9. JQuery发送ajax

9.1. get

$.get(url, [data], [callback], [type])

​ url:请求的 URL 地址

​ data:请求携带的参数

​ callback:载入成功时回调函数

​ type:设置返回内容格式,xml, html, script, json, text, _default

1
2
3
4
//get
$.get('http://127.0.0.1:3700/show/all',"basketball=1",function(data){
console.log(data);
});

9.2. post

$.post(url, [data], [callback], [type])

​ url:请求的 URL 地址

​ data:请求携带的参数

​ callback:载入成功时回调函数

​ type:设置返回内容格式,xml, html, script, json, text, _default

1
2
3
4
// post
$.post('http://127.0.0.1:3700/show/all',"basketball=1",function(data){
console.log(data);
});

9.3. 直接使用ajax

https://jquery.cuishifeng.cn/jQuery.Ajax.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$.ajax({
url: 'http://127.0.0.1:3700/show/all',
// 请求参数
data: "basketball=1",
// 请求方式
method: 'get',
// 响应体类型
dataType: 'json',
// 成功回调
success: function(data){
console.log(data);
},
error:function(){

},
// 超时
timeout: 200,
// 头信息
headers: {
"Content-Type":"applcation/xxx-form-urlencoded"
}

})

10. axios

https://github.com/axios/axios

doc:https://axios-http.com/zh/

插件:https://www.bootcdn.cn/

10.1. get

1
2
3
4
5
6
7
axios.get("/show/all",{
params: {
basketball: 1
}
}).then(function(res){
console.log(res.data);
})

10.2. post

axios.post(url[, data[, config]])

1
2
3
4
5
6
7
8
9
axios.post("/show/all",{
username: 'uname'
},{
params: {
basketball: 1
}
}).then(function(res){
console.log(res.data);
})

10.3. ajax

1
2
3
4
5
6
7
8
9
10
11
12
 axios({
url: "/show/all",
method: 'post',
data: {
username: 'uname'
},
params: {
basketball: 1
}
}).then(function(res){
console.log(res.data);
});

11. fetch

https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API

1
2
3
4
5
6
7
8
9
fetch("http://127.0.0.1:3700/show/all",{
method: 'get'
}).then(res=>{
// 字符串
// return res.text();
return res.json();
}).then(data=>{
console.log(data);
})

12. 同源

同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略。

协议,域名,端口号 必须完全相同

12.1. 解决策略一jsonp

JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持 get 请求

12.1.1. JSONP 怎么工作的?

在网页有一些标签天生具有跨域能力,比如:img link iframe script。JSONP 就是利用 script 标签的跨域能力来发送请求的。

12.1.2. JSONP 的使用

html中的script标签支持跨域

1
2
3
4
5
6
7
app.get("/jsonp",(req,res)=>{
const data = {
username: 'uname'
}
let str = JSON.stringify(data);
res.end(`handle(${str})`);
})

html

1
2
3
4
5
6
<script>
function handle(json){
console.log(json);
}
</script>
<script src="http://127.0.0.1:3700/jsonp"></script>

12.2. JQuery版

1
2
3
4
5
6
7
8
app.get("/jsonp",(req,res)=>{
const data = {
username: 'uname'
}
let str = JSON.stringify(data);
let cb = req.query.callback;
res.end(`${cb}(${str})`);
})

js

1
2
3
$.getJSON("http://127.0.0.1:3700/jsonp?callback=?",function(data){
console.log(data);
})

最终调用的路由为 http://127.0.0.1:3700/jsonp?callback=jQuery360012005959090789764_1655395933862&_=1655395933864

故返回的方法为

1
jQuery360012005959090789764_1655395933862({username: "uname"})

12.3. 解决策略二 CORS

CORS(Cross-Origin Resource Sharing),跨域资源共享。

CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求

跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源

12.3.1. CORS 怎么工作的?

CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行

12.3.2. CORS 的使用

1
2
3
res.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");

res.set("Access-Control-Allow-Origin","*");
本文结束  感谢您的阅读
  • 本文作者: Wang Ting
  • 本文链接: /zh-CN/2019/09/04/AJAX技术/
  • 发布时间: 2019-09-04 14:11
  • 更新时间: 2023-04-15 16:16
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!