原生AJAX

AJAX简介

AJAX全称为Asynchronous JavaScript And XML,就是异步的JS和XML。

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

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

XML简介

XML可扩展标记语言。

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

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

例如,我有一个学生的数据,用xml表示:

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

不过现在已经被JSON取代了。

1
2
3
4
5
{
"name": "lxj",
"age": 18,
"gender": "男"
}

AJAX的特点

AJAX的优点

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

AJAX的缺点

  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)
  3. SEO不友好

AJAX的使用

核心对象

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

使用步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化,设置请求对象和请求url,以及请求参数(get)
xhr.open("get", "http://127.0.0.1:3000/server?a=100");
// 3.发送请求,请求方式为post时,需要传入请求参数('a=100')
xhr.send()
// 4.事件绑定 处理服务端返回的结果
// readyState是xhr对象中的属性,表示状态0 1 2 3 4,4的时候就是接收到全部数据
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var text = xhr.responseText;

// 让id为app的div标签内容更改为获取到的内容
let div = document.getElementById("app");
div.innerHTML = text;
}
}

解决IE缓存问题

在一些浏览器中(IE),由于缓存机制的存在,ajax只会发送第一次请求,剩余多次请求不会再发送给服务器,而是会直接接在缓存中的数据。

解决方式:浏览器缓存是根据url地址来记录的,只需要修改url地址即可避免缓存问题。

1
xhr.open("get", "/textAJAX?t=" + Date.now());

AJAX请求状态

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

  1. 表示当前XMLHttpRequest实例已经生成,但是open()方法还没有被调用
  2. 表示send()方法还没有被调用,仍然可以使用setRequestHeader(),设定HTTP请求头的信息
  3. 表示send()方法已经执行,并且头信息和状态码已经收到
  4. 表示正在接收服务器传来的body部分的数据
  5. 表示服务器数据已经完全接收,或者本次接收已经失败了

AJAX请求超时设定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const xhr = new XMLHttpRequest();
// 设置超时时长
xhr.timeout = 2000;
// 设置超时回调
xhr.ontimeout = () => {
alert('请求超时,请稍后重试');
}
// 设置网络异常回调
xhr.onerror = error => {
alert(error);
}

xhr.open("get", "http://127.0.0.1:3000/server");
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var text = xhr.responseText;
let div = document.getElementById("app");

div.innerHTML = text;
}
}

防止重复提交AJAX请求

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
let isSending = false;
{
if(isSending){
// 上一次请求还没有结果,不能重复发起请求
return;
}
// 发送ajax请求
const xhr = new XMLHttpRequest();
x = xhr;
xhr.timeout = 2000;
isSending = true;
xhr.open("get", "http://127.0.0.1:3000/delay");
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4){
isSending = false
if(xhr.status === 200) {
var text = xhr.responseText;
let div = document.getElementById("app");

div.innerHTML = text;
}
}
}
}

Axios

axios 是一个基于 PromiseHTTP 客户端,用于在浏览器和 Node.js 环境中发送异步网络请求。它是目前前端开发中最流行的请求库之一。

使用axios发送请求

get请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
axios.get('/axios-server', {
// url参数
params: {
id: 100,
vip: 7
},
headers: {
name: "lxj"
}
})
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err);
})
.finally(() => {

})

post请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
axios.post('/axios-server',{
// 请求体
username: 'xh',
age: 18
}, {
// url参数
params: {
id: 100,
vip: 7
},
headers: {
name: "lxj"
}
})
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err);
})
.finally(() => {

})

使用通用方式发送请求

1
2
3
4
5
6
7
8
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone',
},
});

Fetch

Fetch API 是现代浏览器原生内置的 HTTP 请求接口,基于 Promise 设计,用于替代传统的 XMLHttpRequest。它是 Web 标准的一部分,不需要安装任何第三方库。

1
2
3
4
5
6
7
8
9
10
11
12
fetch('http://127.0.0.1:3000/fetch-server',{
// 请求方法
method: 'post',
// 请求头
headers:{
name: 'yxh'
},
// 请求体
body: 'username=admin'
})
.then(res => res.json())
.then(data => console.log(data));

跨域

同源策略

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

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

违背同源策略就是跨域。

如何解决跨域

JSONP

JSONP是什么

JSONP(JSON with padding),是一个非官方的跨域解决方案,只支持get请求。

JSONP是怎么进行工作的

在网页有一些标签天生就有跨域能力,比如:img link iframe script。

JSONP就是利用script标签的跨域能力来发送请求的。

JSONP的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1.动态的创建一个script标签
var script = document.createElement("script");
// 2.设置script的scr,设置回调函数
script.src = "http://127.0.0.1:3000/testAJAX?callback=abc";
function abc(data){
alert(data.name);
}
// 3.将script添加到body中
document.body.appendChild(script);
// 4.服务器中路由的处理
router.get("/testAJAX",(req, res)=>{
console.log('收到请求');
var callback = req.query.callback;
var obj = {
name: 'yxh',
age: 18
}
res.send(callback+"("+JSON.stringify(obj)+")");
})

CORS

CORS是什么

CORS(Cross-Orgin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

CORS怎么工作的

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

CORS的使用

主要是服务端的设置:

1
2
3
4
5
app.get('/server', (req, res) => {
// 设置允许跨域
res.setHeader('Access-Control-Allow-Origin', '*');
res.send('get请求获取成功');
});