Ajax-XMLHttpRequest/JQuery/Axios/Fetch请求,以及JSONP/CORS跨域请求

XMLHttpRequest

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
btn.onclick = function(){
// 1. 创建对象
const xhr = new XMLHttpRequest();
// 2. 初始化 设置请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/server')
// 3. 发送
xhr.send();
// 4. 事件绑定 处理服务端返回的结果
xhr.onreadystatechange = function(){
// readyState 是 xhr 对象中的属性, 表示状态 0 1 2 3 4
//判断 (服务端返回了所有的结果)
if(xhr.readyState === 4){
//判断响应状态码 200 404 403 401 500
if(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;
}else{
}
}
}
}

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
result.addEventListener("mouseover", function(){
// 1. 创建对象
const xhr = new XMLHttpRequest();
// 2. 初始化 设置类型(请求方式)与url
xhr.open('POST', 'http://127.0.0.1:8000/server');
// 设置请求体内容的类型
// xhr.setRequesHeader('Content-Type','application/x-www-from-urlencoded');
// 设置响应体数据的类型
// xhr.responseType = "json";
// 超时设置 (2秒)
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function(){
alert('网络超时,请稍后重试')
}
// 网络异常回调
xhr.onerror = function(){
alert('网络异常,请稍后重试')
}
// 3. 发送 设置请求参数(请求体)
xhr.send('a=100&b=200&c=300');
// 4. 事件绑定
xhr.onreadystatechange = function(){
// 判断
if(xhr.readyState === 4){
if(xhr.status >=200 && xhr.status < 300){
// 处理服务端返回的结果
result.innerHTML = xhr.response;
}
}
}
});

取消请求

1
2
3
btn.onclick = function () {
xhr.abort();
}

重复请求,取消前面请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let xhr = null;
let isSending = false;
btn.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;
}
}
}

JQuery

GET

1
2
3
4
// $.get/post(url, [data], [callback], [type])
$.get("http://127.0.0.1:8000/jquery", {a: 100, b:200}, function(data){
console.log(data);
}, "json") // 响应体数据格式

POST

1
2
3
$.post("http://127.0.0.1:8000/jquery", {a: 100, b:200}, function(data){
console.log(data);
})

通用

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
$.ajax({
// url
url: 'http://127.0.0.1:8000/jquery-server',
// 参数
data: {a:100, b:200},
// 请求类型
type: 'GET',
// 响应体结果
dataType: 'json',
// 成功的回调
success: function(data){
console.log(data);
},
// 超时时间
timeout: 2000,
// 失败的回调
error: function(){
console.log('出错拉~');
},
// 头信息
headers: {
c: 300,
d: 400
}
})

axios

GET

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
axios.defaults.baseURL = "http://127.0.0.1:8000";
axios.get("/axios-server", {
// url 参数
params: {
id: 1,
vip: 7
},
// 请求头信息
headers: {
name: "kong",
age: 22
}
}).then(data => {
console.log(data);
});

POST

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// axios.post(url[, data[, config]])
axios.post("http://127.0.0.1:8000/axios-server", {
username: 123,
password: 456
},{
// url 参数
params: {
id: 1,
vip: 7
},
// 请求头信息
headers: {
name: "kong",
age: 22
}
}).then(data => {
console.log(data);
});

通用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
axios({
method: "POST",
// url
url: "http://127.0.0.1:8000/axios-server",
params: {
id: 2
},
headers: {
a: 100,
b: 200
},
// 请求体
data: {
username: 123,
password: 234,
}
}).then(response => {
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.data);
})

默认配置

1
2
3
4
5
//默认配置
axios.defaults.method = 'GET';//设置默认的请求类型为 GET
axios.defaults.baseURL = 'http://localhost:3000';//设置基础 URL
axios.defaults.params = {id:100}; // params 参数
axios.defaults.timeout = 3000; //超时时间

axios 创建实例对象

1
2
3
4
5
import axios from "axios"
const instance = axios.create({
baseURL: '/api',
timeout: 5000
})

拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 请求拦截器
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 1号');
config.params = {a:100};
return config;
}, function (error) {
return Promise.reject(error);
});

// 响应拦截器
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 1号');
return response.data;
}, function (error) {
return Promise.reject(error);
});

// 设置多个请求拦截器或者多个相应拦截器
// 请求拦截器是 unshift 方法添加到处理函数数组队列
// 响应拦截器是 push 添加到处理函数数组队列
// 按数组顺序处理
promise = [请求拦截器2, 请求拦截器1, 请求, 响应拦截器1, 响应拦截器2]

取消请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let cancelHandle = null;
function request(){
if (cancelHandle !== null) cancelHandle(); // 取消请求
axios({
method: 'GET',
url: 'http://localhost:3000/post',
// 添加取消请求的配置
cancelToken: new axios.CancelToken((cancel)=>{
cancelHandle = cancel; // 将取消请求的回调函数暴露
})
})
}
function cancelRequest(){
cancelHandle()
}

fetch

POST

1
2
3
4
5
6
7
8
9
10
11
12
13
fetch("http://127.0.0.1:8000/fetch-server?vip=10", {
method: "POST",
headers: {
name: "kong"
},
// 请求体
body: "username=admin&password=123456"
}).then(response => {
// return response.text();
return response.json();
}).then(response => {
console.log(response)
})

跨域

JSONP

  • <script>标签支持跨域请求
1
2
3
4
5
6
7
8
9
// html 文件 file://d/json-p.html
<script>
// 供后端调用,该处理数据的函数
function handler(data) {
const rseult = document.getElementById("id");
result.innerHTML = data.name;
}
</script>
<script src="http://127.0.0.1:8000/jsonp-server"></script> // 协议、域名、端口都不同
1
2
3
4
5
6
7
8
9
// 服务端 127.0.0.1:8000
app.all("/jsonp-server", (request, response) => {
const data = {
name: "kong"
};
let str = JSON.stringify(data);
// 返回结果给前端,最终调用了前端定义的handler函数并传参 str
response.end(`handler(${str})`);
})

JSONP跨域实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 前端
<body>
用户名:<input type="text" id="username">
<p></p>
<script>
const input = document.querySelector("input");
function handler(data) {
input.style.border = "solid 1px #f00";
p.innerHTML = data.msg;
}
input.onblur = function () {
let username = this.value;
// 向服务端发送请求 检测用户是否存在
// 创建 script 标签
const script = document.createElement("script");
script.src = "http://127.0.0.1:8000/check-username?username=" + username;
document.body.appendChild(script);
}
</script>
</body>
1
2
3
4
5
6
7
8
9
// 后端
app.all("/check-username", (request, response) => {
const data = {
exist: 1,
msg: "用户名已经存在"
}
let str = JSON.stringify(data);
response.end(`handler(${str})`);
})

JQuery发送JSONP请求

1
2
3
4
5
6
7
// 前端
$.getJSON("http://127.0.0.1:8000/jquery-jsonp-server?callback=?", function(data){
$(#result).html(`
名称:${data.name},
校区:${data.city}
`)
})
1
2
3
4
5
6
7
8
9
10
// 后端
app.all("/jquery-jsonp-server", (request, response) => {
const data = {
name: "kong",
city: ['北京', '上海']
};
let str = JSON.stringify(data);
let callbackHandle = request.query.callback;
response.end(`${callbackHandle}(${str})`);
})

CORS

1
2
3
4
5
6
// 后端
app.all("/cors-server", (request, response) => {
response.setHeader("Access-Control-Allow-Origin", "*"); // 允许任意源
response.setHeader("Access-Control-Allow-Headers", "*"); // 允许任意请求头
response.setHeader("Access-Control-Allow-Method", "*"); // 允许任意请求方法
})