HTTP
-
超文本传输协议:规定互联网客户端、服务器和服务器之间的通信规则
-
通信的内容,称为报文
- 请求报文
- 响应报文
-
报文组成:
- 报文首行
- 报文头
- 空行
- 报文主体
-
请求报文
- 请求首行
- 请求方式 GET(查) POST(增) PUT(全部改) PATCH(部分改) DELETE(删)
- 请求地址 可能携带查询字符串参数(querystring、params)?key=value&key=value
- 请求头
- content-type 请求主体的类型
- 请求主体
- POST PUT PATCH请求方式的请求参数
- 请求首行
-
请求体参数类型
- content-type: application/json json格式的参数 {“name”: “jack”}
- content-type: x-www-form-urlencoded form表单格式的参数 key=value&key=value
-
响应报文
- 响应首行
- 响应状态码status
- 1xx 代表请求还未完成,需要进一步处理
- 2xx 代表请求成功 200
- 3xx 代表请求重定向
- 301 永久重定向
- 302 临时重定向
- 304 走协商缓存
- 4xx 代表客户端错误
- 401 未授权
- 403 禁止
- 404 资源找不到
- 5xx 代表服务器错误
- 500
- 响应状态码status
- 响应首行
原生axios
// 1.创建xhr对象
const xhr = new XMLHttpRequest();
// 2.给xhr绑定onreadystatechange事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status <= 299) {
console.log(xhr.responseText);
console.log(xhr)
}
};
// 3.设置请求信息
xhr.open("GET", "http://localhost:3000/posts");
// 4.发送请求
xhr.send();
xhr封装axios
function axios({
method, // 请求方式
url, // 请求地址
data, // 请求体参数 body
params, // querystring 查询字符串参数
}) {
return new Promise((resolve, reject) => {
method = method.toUpperCase();
// 1. 创建xhr对象
const xhr = new XMLHttpRequest();
// 2. 绑定onreadystatechange事件
// 当readystate发生变化时触发的事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 响应返回了(但是成功、失败不知道)
if (xhr.status >= 200 && xhr.status < 300) {
// 响应成功
const response = {
request: xhr,
status: xhr.status,
data: JSON.parse(xhr.responseText),
};
resolve(response);
} else {
// 响应失败
console.log("error", xhr);
reject("error");
}
}
};
/*
通常情况下:
GET、DELETE请求,只会有查询字符串参数
POST、PUT、PATCH请求,既可以有请求体参数,也可以有查询字符串参数
params: { name: 'jack', age: 18 }
--> url?name=jack&age=18
*/
let qs = "";
if (params) {
// 提取params中所有属性名成为一个数组
// ['name', 'age']
qs = Object.keys(params)
.reduce((p, key) => {
const value = params[key];
return p + `${key}=${value}&`;
}, "?")
.slice(0, -1);
}
// 3. 设置请求信息(请求地址、请求方法。。。)
xhr.open(method, url + qs);
let body = "";
if (
(method === "POST" || method === "PUT" || method === "PATCH") &&
data
) {
// 设置请求头
xhr.setRequestHeader("content-type", "application/json");
body = JSON.stringify(data);
}
// 4. 发送请求
xhr.send(body);
});
}
btn1.onclick = function () {
// 发送GET请求
axios({
method: "GET",
url: "http://localhost:3000/comments",
})
.then((value) => {
// 200-299
console.log("value", value);
})
.catch((reason) => {
console.log("reason", reason);
});
};
btn2.onclick = function () {
// 发送POST请求
axios({
method: "POST",
url: "http://localhost:3000/comments",
data: {
// 请求体参数 body
body: "i like laoluo",
postId: 3,
},
})
.then((value) => {
// 200-299
console.log("value", value);
})
.catch((reason) => {
console.log("reason", reason);
});
};
</script>
取消方式一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button id="btn">发送请求</button>
<button id="btn1">取消请求</button>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script>
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
btn.onclick = function () {
axios({
url: "http://localhost:3000/comments",
cancelToken: source.token,
})
.then((result) => {
console.log("resule", result);
})
.catch((err) => {
console.log("err", err);
});
};
btn1.onclick = function () {
// 取消请求
source.cancel("取消请求了");
};
</script>
</body>
</html>
取消方式二(常用)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button id="btn">发送请求</button>
<button id="btn1">取消请求</button>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script>
let cancel = null;
btn.onclick = function () {
axios({
url: "http://localhost:3000/comments",
cancelToken: new axios.CancelToken(function (c) {
cancel = c;
}),
})
.then((result) => {
console.log("resule", result);
})
.catch((err) => {
if (axios.isCancel(err)) {
console.log("错误是取消请求导致的", err);
return;
}
console.log("err", err);
});
};
btn1.onclick = function () {
// 取消请求
cancel("取消请求了");
};
</script>
</body>
</html>
取消方式三
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button id="btn">发送请求</button>
<button id="btn1">取消请求</button>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script>
let cancel = null;
btn.onclick = function () {
axios({
url: "http://localhost:3000/comments",
cancelToken: new axios.CancelToken(function (c) {
cancel = c;
}),
})
.then((result) => {
console.log(result);
})
.catch((err) => {
console.log(err);
});
};
btn1.onclick = function () {
cancel("quxiaoqingqiu ");
};
</script>
</body>
</html>
server
const express = require("express");
const app = express();
app.get("/comments", (req, res) => {
// 处理跨域 jsop cors
res.set("Access-Control-Allow-Origin", "*");
// 让服务器三秒以后再返回响应
setTimeout(() => {
res.json({
code: 10000,
data: [
{
id: 1,
title: "劳斯宾利法拉利",
},
],
});
}, 3000);
});
app.listen(3000,"localhost",(err)=>{
if (err) {
console.log("err",err);
return
}
console.log("服务器启动成功,请访问http://localhost:3000");
})