使用axios封装网络请求~
网络请求的方式
传统的Ajax | 基于XMLHttprequest(XHR) | 配置和调试混乱 |
---|---|---|
jQuery-Ajax | 为了引入ajax而引入jquery不必要 | |
Vue-resource | 相对jq,Vue-resource体积小很多 | Vue2.0后就不更新了 |
Jsonp | 解决跨域问题 | |
axios |
jsonp:项目的部署在domain1.com服务器上,不能直接访问domain2.com服务器上的资料。这个时候,利用script标签的src来请求数据,将数据当成一个js函数来执行,并且执行过程中传入我们需要json
封装Jsonp的核心就在于监听window上的jsonp进行回调时的名称
为什么选axios?
- 在浏览器中发送XMLHttpRequests请求
- 在node.js中发送http请求
- 支持Promise API
- 拦截请求和响应
- 转换请求和响应数据
axios基本使用
安装
npm i -s axios
引入
import axios from 'axios'
测试
axios({
url: 'url~'
}).then(res => {
console.log(res)
})
为什么可以用.then()?
axios函数的返回值是个Promise对象
为什么不写请求方式?
axios默认请求方式是get
测试网站httpbin.org/
测试接口url~
axios的请求方式
get
可以放参数里
也可以直接axios.get()
axios({
url: 'url~',
method: 'get'
}).then(res => {
console.log(res)
})
axios.get()
带参
axios({
url: 'url~',
}).then(res => {
console.log(res)
})
等价于
axios({
url: 'url~',
// 专门针对get请求参数拼接
params: {
type: sell
page: 3
}
}).then(res => {
console.log(res)
})
post
同理
post请求有请求体
data: {id: 2}
axios.all()
- 返回结果是个数组
- axios.spread可以将数组[res1,res2]展开为res1,res2
同时发送两个请求怎么办?
axios.all([axios({
url: 'url~'
}),axios(
url: 'url~',
params: {
type: 'sell',
page: 3
}
)]).then(res => {consloe.log(res)})
返回结果展开
axios.all([axios({
url: 'url~'
}),axios(
url: 'url~',
params: {
type: 'sell',
page: 3
}
)]).then(axios.spread((res1, res2) => {
console.log(res1)
console.log(res2)
}))
全局配置
当参数固定时,可以抽取出来全局配置
axios.defaults.baseURL = 'url~'
axios.defaults.headers.post[Content-Type] = 'application/x-www-form-urlencoded'
axios实例
const instance1 = axios.create({
baseURL: 'url~'
})
instance1({
url: '/home/multidata',
}).then(res => {
console.log(res)
})
axios封装
项目根目录下新建一个network文件夹,并在该文件夹下新建一个文件request.js
// request.js
import axios from 'axios'
export function request (config, success, failure) {
// 1.创建axios实例
const instance = axios.create({
baseURL: 'url~',
timeout: 5000
})
// 发送真正的网络请求
instance(config)
.then(res => {
success(res)
}).catch(err => {
failure(err)
})
}
在需要用网络请求处
// 引入request模块
import { request } from './network/request'
request({
url: '/home/multidata'
}, res => {
console.log(res)
}, err => {
console.log(err)
})
Promise方式
// request.js
import axios from 'axios'
export function request (config) {
return new Promise((resolve, reject) => {
// 1.创建axios实例
const instance = axios.create({
baseURL: 'url~',
timeout: 5000
})
// 发送真正的网络请求
instance(config)
.then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
在需要用网络请求处
// 引入request模块
import { request } from './network/request'
request({
url: '/home/multidata'
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
为什么axios.create创建出来的instance实例有.then方法?
因为这个方法创建出来的实例是Promise对象实例
所以
最终方案
// request.js
import axios from 'axios'
export function request (config) {
// 1.创建axios实例
const instance = axios.create({
baseURL: 'url~',
timeout: 5000
})
// 发送真正的网络请求
return instance(config)
}
在需要用网络请求处
// 引入request模块
import { request } from './network/request'
request({
url: '/home/multidata'
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
经验
组件对于第三方模块的依赖性不能太强
假如有50组件引入了axios,万一哪一天axios不维护了,那要改50个组件,这种行为很危险
但是一定要用它,怎么办?
封装成独立的模块,组件想用引入就行
当axios哪一天不维护了,也不用全部组件一个一个改
只要修改封装的那一部分代码(换成别的第三方模块)即可
axios拦截器
用于每次发送请求或得到响应之后进行相应的处理
请求拦截
请求拦截一定要返回config,不然请求发不出去啦……
请求拦截一般会有哪些操作?
- 比如config中的一些信息不符合服务器的要求(header,当然header也可以在公共参数那里设置)
- 比如每次发送网络请求时,都希望在界面中显示一个请求的动画或图标
- 某些网络请求(登陆token),必须携带一些特殊信息,不然执行相关操作(如未登录跳转到登陆界面)
import axios from 'axios'
export function request (config) {
// 1.创建axios实例
const instance = axios.create({
baseURL: 'url~',
timeout: 5000
})
// 2.请求拦截
instance.interceptors.request.use(config => {
console.log(config)
return config
}, err => {
console.log(err)
})
// 3.发送真正的网络请求
return instance(config)
}
响应拦截
响应拦截一定要返回res,不然拿不到响应结果啦……
不过只要返回res.data就行,其信息不需要
import axios from 'axios'
export function request (config) {
// 1.创建axios实例
const instance = axios.create({
baseURL: 'url~',
timeout: 5000
})
// 2.响应拦截
instance.interceptors.response.use(res => {
console.log(config)
return res
}, err => {
console.log(err)
})
// 3.发送真正的网络请求
return instance(config)
}
转载自:https://juejin.cn/post/7073097106105319431