优缺点
-
优点
- 可以无需刷新页面与服务器端进行通信
- 允许根据用户事件来更新部分页面内容
-
缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO 不友好
超时与网络异常
const xhr = new XMLHttpRequest();
// 超时设置
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){
// ....
}
}
}
取消请求
// 调用 abort 方法
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http:127.0.0.1:8000/delay');
xhr.send();
xhr.abort();
请求重复发送问题
// 调用 abort 方法
const btns = document.querySelectorAll('button');
let isSending = false;
let xhr = null;
btns[0].onclick = function () {
if(isSending) xhr.abort();
let 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;
if(xhr.status >= 200 && xhr.status < 300){
// ....
}
}
}
}
jQuery 通用方法
$.ajax({
url: 'http:127.0.0.1:8000/delay',
data: {a:100, b:200},
type: 'GET',
dataType: 'json',
sucess: function (data) {
console.log(data);
}
timeout: 2000,
error: function () {
console.log('出错了');
}
})
Axios 发送 Ajax 请求
// 1.get请求
axios.get('/axios-server', {
//url参数
params: {
id: 100,
vip: 7
},
//请求头信息
headers: {
name: 'xxx',
age: 20
}
}).then(value => {
console.log(value);
})
// 2.post请求
axios.post('/axios-server', {
username: 'admin',
password: 'admin'
}, {
// url参数
params: {
id: 100,
vip: 9
},
// 请求头参数
headers: {
name: 'xxx',
age: 20
}
}
})
// 3.通用方法
axios({
method: 'POST',
url: 'axios/server',
// url参数
params: {
vip: 10,
level: 20
}
// 请求头
headers: {
a: 100,
b: 200
},
// 请求体
data: {
uername: 'admin',
password: 'admin'
}
}).then(response => {
// 响应状态码
console.log(response.status);
// 响应字符串
console.log(response.statusText);
// 响应头信息
console.log(response.headers);
// 响应体
console.log(response.data);
})
fetch 函数发送 Ajax 请求
fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
method: 'POST',
headers: {
name: 'xxx'
},
body: 'username=admin&password=admin'
}).then(response => {
return response.text();
}).then(response => {
console.log(response);
})
跨域
1. 同源策略
- 同源: 协议、域名、端口号必须完全相同
- 违背同源策略就是跨域
2. 解决方法
- JSONP
- CORS
JSONP
- JSONP(JSON with Padding),是一个非官方的跨域解决方案,只支持 get 请求
- 网页中,有一些标签天生具有跨域能力,比如 img、link、iframe、script,JSONP 就是利用 script 标签的跨域能力来发送请求
- 使用
- 动态创建一个 script 标签
var script = document.createElement("script");
- 设置 script 的 src,设置回调函数
script.src = "http://localhost:3000/testAjax?callback=abc";
- 将 script 插入到文档中
document.body.appendChild(script);
- 服务器中路由的处理
- 动态创建一个 script 标签
router.get("/testAJAX" , function (req , res) {
console.log("收到请求");
var callback = req.query.callback;
var obj = {
name:"孙悟空",
age:18
}
res.send(callback+"("+JSON.stringify(obj)+")");
});
- jQuery 发送 JSONP 请求
$('button').eq(0).click(function () {
$.getJSON('http://127.0.0.1:8000/jsonp-server?callback=?', function (data) {
console.log(data);
})
})
CORS
- CORS(Cross-Origin Resource Sharing),跨域资源共享
- CORS 是官方的跨域解决方案,特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 请求和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
- 工作方式:CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
- 使用:主要是服务器端的设置
router.get("/testAJAX" , function (req , res) {
// 通过 res 来设置响应头,来允许跨域请求
// res.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");
res.set("Access-Control-Allow-Origin","*");
res.send("testAJAX 返回的响应");
})