# AXIOS
# 一、网络请求模块的选择
# 1】模块选择
# ①选择一:传统的Ajax是基于XMLHTTPRequest(XHR)
为什么不选择它?
- 配置和调用方式等非常混乱
- 编码起来看起来很蛋疼
- 所以真实开发中很少直接使用,而是使用jQuery-Ajax
# ②选择二:在前面的学习中,我们经常会使用jQuery-Ajax
- 相对于传统的Ajax非常好用
为什么不选择它?
- 首先,我们先明确一点:在Vue的整个开发中都是不需要使用jQuery了
- 那么,就意味着为了方便我们进行一个网络请求,特意引用一个jQuery
- 完全没必要为了用网络请求就引用这个重量级框架
# ③选择三:官方在Vue1.x的时候,推出了Vue-resource
- Vue-resource的体积相对于jQuery小很多
- 另外Vue-resource是官方推出的
为什么不选择它?
- 在Vue2.0推出之后,Vue作者就在GitHub的Issues中说明了去掉Vue-resource,并且以后不再更新
- 那么意味着Vue-resource不再支持新的版本,也不再继续更新维护。对以后的项目开发和维护都存在很大的隐患
# ④选择四:axios框架
axios有很多的有点,并且用起来也非常方便
为什么选择axios:
- 在浏览器中发送XMLHTTPRequests请求
- 在node.js中发送http请求
- 支持Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 等等
# 2】jsonp网络请求方式
在前端开发中,我们一种常见的网络请求方式就是jsonp
- 使用jsonp最主要的原因往往是为了解决跨域访问的问题
jsonp的原理是:
- jsonp的核心在于通过
<script>
标签在src来帮助我们请求数据 - 原因是我们的项目部署在domain1.com服务器上时。是不能直接访问domain2.com服务器上的资料的
- 这个时候,我们利用
<script>
标签的src帮助我们去服务器请求到数据,将数据当做一个JavaScript的函数来执行,并且执行的过程中传入我们需要的json - 所以,封装jsonp的核心就在于我们监听window上的jsonp进行回调时的名称
# 二、axios框架的基本使用
# 1】安装axios
npm install axios --save
# 2】axios的多种用法
- axios({config})
- axios.request({config})
- axios.get(url [,config])
- axios.delete(url [,config])
- axios.head(url [,config])
- axios.post(url [,data [,config] ])
- axios.put(url [,data [,config] ])
- axios.patch(url [,data [,config] ])
# 3】具体实现代码:
注意这里axios不需要new,直接使用该方法即可
在axios框架中也是使用了**.then()**来获得结果->说明是使用了Promise
import Vue from 'vue'
import App from './App'
import axios from 'axios'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(App)
})
//方式一
axios({
url:'http://123.207.32.32:8000/home/multidata',
//method:'post'
//默认使用get
}).then(res=>{
console.log(res)
})
//方式二
axios({
url:"http://123.207.32.32:8000/home/data?type=pop&page=1",
//使用get请求
}).then(res=>{
console.log(res)
})
//和上面方式二是相同的
axios({
url:"http://123.207.32.32:8000/home/data",
//专门针对get请求的参数拼接
params:{
type:'pop',
page:1
}
}).then(res=>{
console.log(res)
})
# 三、axios.all()发送并发请求
使用**axios.all()方法,和ES6中的promise.all()**方法差不多
- 有时候我们可能需求同时发送两个请求
- 使用axios.all(),可以放入多个请求的数组
- axios.all([axios(),...,axios()])返回的结果是一个数组,使用axios.spread()可将数组[res1,...,res2]展开为res1,...,res2
# 具体代码实现:
axios.all([axios({
url:'http://123.207.32.32:8000/home/multidata'
}),axios({
url:"http://123.207.32.32:8000/home/data",
params:{
type:'pop',
page:1
}}
)]).then(axios.spread((res1,res2)=>{
console.log(res1);
console.log(res2);
}))
//.then(res=>{console.log(res)})
# es6解构赋值
//es6语法解构赋值
//对象解构:
const obj={
name:'kobe',
age:30
}
const {name,age} = obj;
//数组解构:
const names=['why','kobe','james'];
//const name1=names[1]
//const name2=names[2]
//const name3=names[3]
const[name1,name2,name3] = names;
# 四、axios的全局配置
- 事实上,在开发中可能很多参数都是固定的,比如BaseURL是固定的
- 这个时候我们可以进行一些抽取,也可以利用axios的全局配置
- 使用axios.defaults属性
axios.defaults.baseURL = '123.207.32.32:8000'
axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded'
# 五、常见的axios配置选项
- 请求地址
- url:'/user'
- 请求类型(默认为get方式)
- method:'get'
- 请求根路径
- baseURL:'http://www.mt.com/api'
- 请求前的数据处理
- transformRequest:[function(data){}]
- 请求后的数据处理
- transformResponse:[function(data){}]
- 自定义请求头
- headers:{'x-Requested-With':'XMLHttpRequest'}
- URL查询对象(只有get需要配置拼接params)
- params:{id:12}
- 查询对象序列化函数
- paramsSerializer:function(params){}
- request body(post方式才需要把请求参数放在data中)
- data:{key:'aa'}
- 超时设置ms
- timeout:1000
- 跨域是否带Token
- withCredentials:false
- 自定义请求处理
- adapter:function(resolve,reject,config){}
- 身份验证信息
- auth:{uname:' ',pwd:'12'}
- 响应的数据格式json/blob/document/arraybuffer/text/stream
- responseType:'json'
# 六、axios的实例
# 1】为什么要创建axios的实例?
- 当我们从axios模块中导入对象时,使用的实例是默认的实例
- 当给该实例设置一些默认配置时,这些配置就被固定下来了
- 但是后续开发中,某些配置可能会不太一样
- 比如某些请求需要使用特定的baseURL或者timeout或者content-Type等
- 这时候,我们就可以创建新的实例,并且传入属于该实例的配置信息
# 2】使用axios.create()方法
有时候不使用全局的axios配置时,我们就需要创建axios实例。
const instance1=axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
instance1({
url:'home/multidata'
}).then(res=>{
console.log(res);
})
instance1({
url:'home/data',
params:{
type:'pop',
page:1
}
}).then(res=>{
console.log(res);
})
# 七、axios的模块封装
# 1】通过增加函数型参数(回调函数)
# src/network/request.js
import axios from 'axios'
export function request(config,success,failure){
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
//发送真正网络请求
instance(config).then(res=>{
success(res)
}).catch(err=>{
failure(err)
})
}
# main.js
//5.封装request模块
import {request} from './network/request'
request({
url:'/home/multidata'
},res=>{
console.log(res);
},err=>{
console.log(err);
})
# 2】把传入的唯一参数当成对象来处理(对象中设置回调函数)
# src/network/request.js
import axios from 'axios'
export function request(config){
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
//发送真正网络请求
instance(config.baseConfig).then(res=>{
config.success(res)
}).catch(err=>{
config.failure(err)
})
}
# main.js
import {request} from './network/request'
request({
baseConfig:{url:'/home/multidata'},
success(res){
console.log(res);
},
failure(err){
console.log(err);
}
})
# 3】使用ES6语法的Promise
# src/network/request.js
import axios from 'axios'
//方式三
export function request(config){
//包装一个Promise
return new Promise((resolve,reject)=>{
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
//发送真正网络请求
instance(config).then(res=>{//这个then是在获取结果
resolve(res)//此时这个resolve是需要在Promise()对象后面.then进行处理
}).catch(err=>{
reject(err)
})
})
}
# main.js
import {request} from './network/request'
request({
url:'/home/multidata'
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err)
})
# 4】axios实例的返回类型本来就是Promise类型,不需要再次包装一次(最终推荐)
# src/network/request.js
import axios from 'axios'
//方式四
export function request(config){
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
//发送真正网络请求
return instance(config)
//直接return instance,因为他axios实例的返回值本身就是Promise类型
//所以不需要再return new Promise()
}
# main.js
import {request} from './network/request'
request({
url:'/home/multidata'
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err)
})
# 八、axios拦截器的使用
- axios提供了拦截器,用于我们在发送每次请求或者得到响应后,进行相应的处理
# 1】axios的请求拦截
import axios from 'axios'
export function request(config){
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
//2.axios的请求拦截
instance.interceptors.request.use(config=>{
console.log(config);//请求发送成功就会进入use的第一个参数
//在拦截到请求之后,①可以对请求的信息进行修改
//②希望在发送请求之后界面出现请求图标向用户显示
//③某些网络请求(比如登陆携带token),必须携带一些特殊的信息
...
return config// 返回一个config,否则发出的请求被拦截,正常返回的结果拿不到,所以必须要return一个config
},err=>{
console.log(err);
})
//3.发送真正网络请求
return instance(config)
//直接return instance,因为他axios实例的返回值本身就是Promise类型
}
# 2】axios的响应拦截
import axios from 'axios'
export function request(config){
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
//2.axios的响应拦截
instance.interceptors.response.use(res=>{
console.log(res);
return res.data;//也必须要返回响应拦截之后的结果,否则axios正常响应的结果main.js中拿不到
},err=>{
console.log(err);
})
//3.发送真正网络请求
return instance(config)
//直接return instance,因为他axios实例的返回值本身就是Promise类型
}
[客户端]----发送请求(请求拦截)---->[服务器]----响应结果(响应拦截)---->[客户端]