🌈个人主页:前端青山
🔥系列专栏:Vue篇
🔖人终将被年少不可得之物困其一生
依旧青山,本期给大家带来Vue篇专栏内容:前端网络请求:从 XMLHttpRequest 到 Axios
前言
在网络应用中,前后端的数据交互是必不可少的一部分。本文将带你从最基本的 XMLHttpRequest 开始,逐步了解并掌握 jQuery、fetch 和 Axios 这几种常用的前端网络请求方式。每种方式都有其特点和适用场景,希望通过本文的介绍,你能找到最适合项目的解决方案。
1.1 XMLHttpRequest
浏览器对XMLHttpRequest对象的支持度不足, 创建 XMLHttpRequest 对象时需要对IE浏览器做的兼
容解决。 - ActiveXObject
回顾:XHR
-
readyState
-
0-4,0表示未初始化,4表示请求已完成
-
status(HTTP响应状态码)
-
200:OK,成功
-
3XX【重定向系列的状态码】
-
301:永久重定向
-
302:临时重定向
-
307:内部浏览器(缓存)重定向
-
-
4XX【错误系列】
-
400:bad request,错误请求
-
401:鉴权失败
-
403:禁止访问
-
404:找不到对应的资源
-
405:方法不被允许
-
-
5XX【服务器错误,环境问题】
-
500:服务器内部错误(代码、环境问题)
-
502:bad Getway,错误网关
-
使用XHR请求全国高校数据接口
接口地址
-
https://api.i-lynn.cn/college
-
只循环展示 list 信息即可
-
接口可以直接被跨域请求
案例效果
-
参考代码:
<!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><div id="app"></div>
</body>
<script>// 1.生成XHR对象var xhr = new XMLHttpRequest()// 2.绑定回调函数 xhr.onreadystatechange = function () {// 3. 判断是否成功 if (xhr.readyState === 4 && xhr.status === 200) {const list = JSON.parse(xhr.responseText).dataconsole.log(list)}}// 4. 打开请求xhr.open('GET', 'https://api.i-lynn.cn/college')// 5.发送请求xhr.send()
</script>
</html>
1.2 jQuery
jQuery类的引入解决自己写兼容的烦恼,但现在只是使用了jQuery库中的网络请求功能,而jQuery中大量的dom的方法都是无效引入了,有点大材小用的意思。
$.ajax({ url, type:get/post, data, dataType:json/text/xml/html/jsonp success:function(res){}, error:function(){}
})
$.get(url,data,callback,dataType)
$.post(url,data,callback,dataType)
<!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><div id="app"><ul><li v-for="(item,index) of list" :key = "index">{{ item.area }}</li></ul></div>
</body>
<script src="lib/jquery.min.js"></script>
<script src="lib/vue.js"></script>
<script>new Vue({el: '#app',data: {list: []},async mounted () {// async await// async 加载函数上,表示函数内部有异步操作// await 记载异步操作前,把异步操作写为同步const res = await $.get("https://api.i-lynn.cn/college", 'json')console.log(res)this.list = res.data.list}})
</script>
</html>
async:关键词,用于函数声明关键词 function 之前,标记当前的函数为异步函数
await:关键词,让当前关键词的行代码执行之后等到到结果之后再去执行后续代码
1.3 fetch
由HTML5提供的内置API
更加简单的数据获取方式,功能更强大、灵活,可以看作是xhr的升级版
基于Promise实现
fetch支持很多请求方式,但默认为 GET 请求,如果需要使用其他方式可以通过第二个自选参数的 method 选项去指定
fetch(url[,some settings]).then(fn2) .then(fn3) ... .catch(fn)
// 通过url表达式来传递数据
fetch("http://xxx/?id=123") .then(res => res.json()) .then(data => console.log(data));
// post标准提交
fetch("http://xxxx/post", { method: "post", body: "uname=lisi&pwd=123", headers: { "Content-Type": "application/x-www-form-urlencoded"}
}).then(res => res.json()) .then(data => console.log(data));
// post提交json数据
fetch("http://localhost:3000/books", { method: "post", body: JSON.stringify({ uname: "lisi", pwd: "123", }), headers: { "Content-Type": "application/json", }
}).then(res => res.json()) .then(data => console.log(data));
注意:fetch 不会发送 cookies。除非你使用了credentials 的初始化选项 credentials: "include"
在上述代码示例中我们会看到有个 json() 方法,它是fetch的响应结果处理方法,fetch的常用响应
结果处理方法有:
-
text():将返回体处理成字符串类型
-
json():返回结果和JSON.parse(responseText)一样
使用fetch方式改写 XHR 部分案例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>06 fetch</title>
</head>
<body><div id="app"><ul><li v-for="item of list" :key="item.proid">{{ item.proname }}</li></ul><input type="text" v-model="loginname"><input type="text" v-model="password"><button @click="login">登录</button></div>
</body>
<script src="lib/vue.js"></script>
<script>new Vue({el: '#app',data: {list: [],loginname: '15635878563',password: '123456'},mounted () {// get请求fetch('http://182.44.11.110/api/pro/list?limitNum=1').then(res => res.json()) // 需要把promise的对象转换为json对象.then(res => {console.log(res)this.list = res.data})},methods: {// post请求login () {fetch('http://http://182.44.11.110/api/user/login', {method: 'post',body: JSON.stringify({ loginname: this.loginname, password: this.password }),headers: {'Content-Type': 'application/json'}}).then(res => res.json()).then(res => {console.log(res)})}}})
</script>
</html>
1.4 axios
1.4.1 基本使用
文档:https://www.kancloud.cn/yunye/axios/234845
axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和node.js中。axios是vue作者推荐使用
的网络请求库,它具有以下特性:
-
支持浏览器和node.js
-
支持promise
-
能够拦截 请求和响应
-
自动转换json数据
axios的浏览器支持
在使用axios之前需要在对应的模板文件中引入axios的js库文件,随后按照以下用法使用axios:
// GET请求方式
axios.get('/get_data?id=10010').then(ret => console.log(ret.data))
axios.get('/get_data',{ params: { id: 10010, name: 'zhangsan', age: 26 } }).then(ret => console.log(ret.data))
//POST请求方式
axios.post('/set_data', { firstName: 'zhang', lastName: 'san'
}).then(ret => { })
axios({ method: 'post', url: 'set_data', timeout: 1000, headers: {'X-Custom-Header': 'foobar'}, data: { firstName: 'zhang', lastName: 'san' }
}).then(ret => { })
当然axios除了支持传统的 GET 和 POST 方式以外,常见的请求方式还支持:
-
put:修改数据
-
delete:删除数据
以上方的axios请求示例为例,axios响应结果( ret )的主要属性有:
-
data:实际响应回来的数据(最常用)**
-
headers:响应头信息
-
status:响应状态码
-
statusText:响应状态信息
另外需要注意的是,在使用axios发送请求之前它允许我们通过全局配置做一些设置,这样可以方便后续的请求操作,例如:
-
axios.defaults.timeout = 3000【设置超时时间】
-
axios.defaults.baseURL = 'http://localhost/app'【设置默认地址】
-
axios.defaults.headers['token'] = '123123123'【设置请求头信息,通用头信息】
-
axios.defaults.headers.get['_token'] = '123123'
-
axios.defaults.headers.post['_token'] = '123123'
-
axios.defaults.headers.common['_token'] = '123123'【通用头信息,common可以不写】
-
注意:
axios发送post请求的时候,默认发送json格式数据
如果需要发送post表单类型请求,则需要指定请求头
axios.post('college',{ username: 'zhangsan', age: 22
},{ headers: { "Content-Type": "application/x-www-form-urlencoded" }
}).then(ret => this.list = ret.data.list)
使用axios方式改写 XHR 部分案例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>07 axios</title>
</head>
<body><div id="app"><ul><li v-for="item of list" :key="item.proid">{{ item.proname }}</li></ul><input type="text" v-model="loginname"><input type="text" v-model="password"><button @click="login">登录</button></div>
</body>
<script src="lib/vue.js"></script>
<script src="lib/axios.min.js"></script>
<script>// http://121.89.205.189/apidoc/new Vue({el: '#app',data: {list: [],loginname: '18813007814',password: '123456'},mounted () {// get请求// fetch('http://182.44.11.110/api/pro/list?limitNum=1')// .then(res => res.json()) // 需要把promise的对象转换为json对象// .then(res => {// console.log(res)// this.list = res.data// })// axios.get('http://182.44.11.110/api/pro/list')// .then(res => {// console.log(res)// this.list = res.data.data// })// axios.get('http://182.44.11.110/api/pro/list?limitNum=2')// .then(res => {// console.log(res)// this.list = res.data.data// })axios.get('http://182.44.11.110/api/pro/list', { // 推荐使用他传递参数params: {limitNum: 3}}).then(res => {console.log(res)this.list = res.data.data})},methods: {// post请求login () {// fetch('http://182.44.11.110/api/user/login', {// method: 'post',// body: JSON.stringify({ loginname: this.loginname, password: this.password }),// headers: {// 'Content-Type': 'application/json'// }// }).then(res => res.json())// .then(res => {// console.log(res)// })axios.post('http://182.44.11.110/api/user/login', {loginname: this.loginname,password: this.password}).then(res => {console.log(res)})}}})
</script>
</html>
1.4.2 拦截器
目的:在请求 发出去之前 / 收到响应之后 做一些操作
请求拦截器
axios.interceptors.request.use(function(config){ // 在请求发出去之前进行一些信息设置 return config;
},function(err){ // 处理响应的错误信息
});
响应拦截器
axios.interceptors.response.use(function(res){ // res为axios对象 return res;
},function(err){ // 处理响应的错误信息
});
<!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><div id="app"><ul><li v-for="(item,index) of list" :key = "index">{{ item.area }}</li></ul></div>
</body>
<script src="lib/vue.js"></script>
<script src="lib/axios.min.js"></script>
<script>axios.interceptors.request.use(function(config){ // 在请求发出去之前进行一些信息设置 console.log('loading......')return config; },function(err){ // 处理响应的错误信息 });
axios.interceptors.response.use(function(res){ // res为axios对象 console.log('loading end')return res; },function(err){ // 处理响应的错误信息 });new Vue({el: '#app',data: {list: []},mounted () {// axios.get('https://api.i-lynn.cn/college')// .then(res => {// console.log(res)// this.list = res.data.data.list// })axios({url: 'https://api.i-lynn.cn/college',method: 'GET',headers: {'content-type': 'application/json'}}).then(res => {console.log(res)this.list = res.data.data.list})}})
</script>
</html>
总结
通过本文的介绍,我们从最基础的 XMLHttpRequest 逐步过渡到了现代的 Axios,每一种请求方式都有其独特的优势和适用场景。XMLHttpRequest 虽然历史悠久,但依然在某些场景下有其价值;jQuery 简化了兼容性问题,但引入了额外的库;fetch 是原生的现代 API,简洁且功能强大;Axios 则是 Vue 官方推荐的库,支持 Promise,使用起来非常方便。希望本文能帮助你在实际项目中选择合适的网络请求方式。