前言
前几天晚上比较无聊,又不是很想学习,就在那里刷小视频,刷到了小满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
| var xhr = new XMLHttpRequest();
xhr.open('GET', '你的文件URL', true);
xhr.responseType = 'blob';
xhr.onload = function() { if (this.status === 200) { var blob = this.response; var blobUrl = URL.createObjectURL(blob); var downloadLink = document.createElement('a'); downloadLink.href = blobUrl; downloadLink.download = '文件名.扩展名'; downloadLink.click(); URL.revokeObjectURL(blobUrl); } };
xhr.send();
|
中断请求 和 设置超时时间
中断请求只需要调用 xhr.abort(); 即可
并且会有一个中断的回调
1
| xhr.addEventListener('abort', function (event) { console.log('我被中断了'); });
|
超时时间可以设置timeout 参数
同样有一个超时回调
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; 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 }) 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
| axios({ url: 'api/XXX', method: 'post', onDowbloadProgress: function (e) { if(e.lengthComputable){ const progress = Math.floor( (e.loaded / e.total) * 100, ); } } })
|
结语
本篇文章就到这里了,更多内容,敬请期待,债见~