请求精进与回顾学习
发表于:2024-04-07 |

前言

前几天晚上比较无聊,又不是很想学习,就在那里刷小视频,刷到了小满zs的网络课,我很早之前就知道他了,看到过他csdn的文章,知道他挺厉害的,但是他的视频内容我没拜读过,看了下视频,还是讲解挺好的,甚至不输一些教育机构的东西。好了,废话不多说,这里我按照他的思路,也重新学习一下请求这块的内容。

学习内容

如果大家想看人家原版本的东西,我把链接放这里了。
博客:https://blog.csdn.net/qq1195566313/category_12312263.html
视频:https://www.bilibili.com/video/BV1rL411a7UN/?spm_id_from=333.999.0.0

本文总体概要

我就按照我自己的思路回顾精进一下了,每种请求实现
1.请求
2.处理结果(成功和失败)
3.请求进度
4.取消请求

XMLHttpRequest

首先就来介绍一下ajax的XMLHttpRequest请求

请求与处理结果

我们都知道如何发送一个简单的XMLHttpRequest请求,大概内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script setup>
const sendHttp=()=>{
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:5173/api/test')
xhr.onload = function() {
if (xhr.status === 200) {
console.log(xhr.responseText)
}
else {
console.log('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send();
}
</script>

<template>
<button @click="sendHttp">
测试
</button>
</template>

我们看一下这个sendHttp的函数,我使用new实例化了XMLHttpRequest,之后就使用这个实例区发送了一个get请求,这里的5173端口是我前端启动服务的端口号,这里的api是我用来代理的,在vite.config.js中加上

1
2
3
4
5
6
7
8
9
server:{
proxy:{
'/api': {
target: 'http://localhost:9527',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}

如果是要携带参数,那就自己把参数拼接到地址上,比如http://localhost:5173/api/test?name=codesigner&age=24

如果我们要发post的json请求呢?其实也很简单,只需要

1
2
3
4
5
6
7
8
9
10
11
12
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:5173/api/test')
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status === 200) {
console.log(xhr.responseText)
}
else {
console.log('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send(JSON.stringify({name:'codesigner',age:24}));

发送post 请求 application/x-www-form-urlencoded

1
2
3
4
5
6
7
8
9
10
11
12
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:5173/api/test')
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
if (xhr.status === 200) {
console.log(xhr.responseText)
}
else {
console.log('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send("name=codesigner&age=24");

上传文件,此时浏览器会自动设置请求头为 multipart/form-data,并且浏览器会自动添加 boundary 分割线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:3000/api/upload')
xhr.onload = function () {
if (xhr.status === 200) {
console.log(xhr.responseText)
}
else {
console.log('Request failed. Returned status of ' + xhr.status);
}
};

let file = this.files[0];
let formData = new FormData();
formData.append('file', file);
xhr.send(formData);

同样的,xhr也可以获取blob数据

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
// 创建一个新的XMLHttpRequest对象
var xhr = new XMLHttpRequest();

// 配置请求类型和URL
xhr.open('GET', '你的文件URL', true);

// 设置响应类型为blob
xhr.responseType = 'blob';

// 处理请求加载完成的情况
xhr.onload = function() {
if (this.status === 200) {
// 请求成功,这里的this.response就是返回的blob对象
var blob = this.response;

// 对blob进行操作,比如使用createObjectURL创建一个URL来下载或者使用FileReader读取内容等
var blobUrl = URL.createObjectURL(blob);

// 例如,使用blobUrl创建一个链接来下载文件
var downloadLink = document.createElement('a');
downloadLink.href = blobUrl;
downloadLink.download = '文件名.扩展名';
downloadLink.click();

// 注意:不要忘记在完成操作后释放blob URL
URL.revokeObjectURL(blobUrl);
}
};

// 发送请求
xhr.send();

中断请求 和 设置超时时间

中断请求只需要调用 xhr.abort(); 即可

并且会有一个中断的回调

1
xhr.addEventListener('abort', function (event) { console.log('我被中断了'); });

超时时间可以设置timeout 参数

1
xhr.timeout = 3000;

同样有一个超时回调

1
xhr.addEventListener('timeout', function (event) { console.log('超时啦'); });

请求进度

1
2
3
xhr.addEventListener('progress', function (event) {
console.log(`请求进度:${(event.loaded / event.total * 100).toFixed(2)}%`);
});

fetch

fetch的返回格式

1.text(): 将响应体解析为纯文本字符串并返回。
2.json(): 将响应体解析为JSON格式并返回一个JavaScript对象。
3.blob(): 将响应体解析为二进制数据并返回一个Blob对象。
4.arrayBuffer(): 将响应体解析为二进制数据并返回一个ArrayBuffer对象。
5.formData(): 将响应体解析为FormData对象。

请求与处理结果

get请求

1
2
3
4
5
6
fetch('http://localhost:3000/api/test').then(res => {
console.log(res);
return res.text()
}).then(res => {
console.log(res);
})

post请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fetch('http://localhost:3000/api/test',{
method:'POST',
headers:{
'Content-Type':'application/json'
},
body:JSON.stringify({
name:'codesigner',
age:24
})
}).then(res => {
console.log(res);
return res.json()
}).then(res => {
console.log(res);
})

中断请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const abort = new AbortController()
fetch('http://localhost:3000/api/test',{
method:'POST',
headers:{
'Content-Type':'application/json'
},
body:JSON.stringify({
name:'codesigner',
age:24
})
}).then(res => {
console.log(res);
return res.json()
}).then(res => {
console.log(res);
})

document.querySelector('#stop').addEventListener('click', () => {
console.log('stop');
abort.abort()
})

请求超时

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
const controller = new AbortController();
const signal = controller.signal;

const timeout = 3000; // 设置超时时间为5000毫秒

setTimeout(() => {
controller.abort(); // 如果在指定时间内没有完成请求,则中止请求
}, timeout);

fetch('http://localhost:5173/api/test', { signal })
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text();
})
.then(text => {
console.log(text);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Fetch request timed out');
} else {
console.error('Fetch error:', error);
}
});

请求进度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const sendFetch = async () => {
const data = await fetch('http://localhost:3000/api/txt',{
signal:abort.signal
})
//fetch 实现进度条
const response = data.clone()
const reader = data.body.getReader()
const contentLength = data.headers.get('Content-Length')
let loaded = 0
while (true) {
const { done, value } = await reader.read()
if (done) {
break
}
loaded += value?.length || 0;
console.log(`进度${(loaded / contentLength * 100).toFixed(2)} + '%'`)
}
const text = await response.text()
console.log(text);
}

axios

最后,再来讲讲我们常见的axios吧,现在基本上vue,react的项目里面用的都是这个,我们就直接跳过请求和处理结果这块

请求超时

这个非常简单,只需要在axios.create创建实例的时候,你把{….,timeout:5000,…}给加进去就行了

取消请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const CancelToken = axios.CancelToken;
let cancel;

axios.get('/xxxx', {
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});

// 取消请求(在需要的时候)
cancel('Operation canceled by the user.');

进度条

在使用axios进行HTTP请求时,可以通过监听HTTP事件来实现进度条的功能。axios本身不直接支持进度事件,但可以通过axios的拦截器和原生的XMLHttpRequest来实现。

如果是上传和下载文件的话
这个是上传的:

1
2
3
4
5
6
7
8
9
10
11
axios({
url: 'api/XXX',
method: 'post',
onUploadProgress: function (e) {
if(e.lengthComputable){
const progress = Math.floor(
(e.loaded / e.total) * 100,
);
}
}
})

这个是下载的

1
2
3
4
5
6
7
8
9
10
11
12
// 函数 onDownLoadProgress
axios({
url: 'api/XXX',
method: 'post',
onDowbloadProgress: function (e) {
if(e.lengthComputable){
const progress = Math.floor(
(e.loaded / e.total) * 100,
);
}
}
})

结语

本篇文章就到这里了,更多内容,敬请期待,债见~

上一篇:
使用pdfjs预览pdf文件
下一篇:
【Python学习】02-Python爬虫