每日一问の二:uniapp中http请求能不能使用axios,如何兼容App?
每日一问の二:uniapp中http请求能不能使用axios,如何兼容App?
- 使用 npm install axios 命令安装 axios
- 新建一个文件夹再建一个 .js 后缀文件放axios封装代码
import Vue from "vue" import axios from "axios" // create an axios instance const service = axios.create({ baseURL: ‘https://simplicity.sankuanedu.com’, // url = base url + request url //withCredentials: true, // send cookies when cross-domain requests 注意:withCredentials和后端配置的cross跨域不可同时使用 timeout: 6000, // request timeout crossDomain: true }) // request拦截器,在请求之前做一些处理 service.interceptors.request.use( config => { if (store.state.token) { // 给请求头添加user-token config.headers[“user-token”] = store.state.token; } console.log(‘请求成功’) return config; }, error => { console.log(error); return Promise.reject(error); } ); //配置成功后的拦截器 service.interceptors.response.use( res => { if (res.data.status<=350) { return res.data } else { return Promise.reject(res.data.msg); } }, error => { if (error.response.status) { switch (error.response.status) { case 401: break; default: break; } } return Promise.reject(error) } )
- 在main.js中放入这段自定义适配器的代码,就可以实现uniapp的app和小程序开发中能使用axios进行跨域网络请求,并支持携带cookie
import axios from "./utils/axios.js" Vue.prototype.$axios = axios axios.defaults.adapter = function(config) { return new Promise((resolve, reject) => { console.log(config) var settle = require(‘axios/lib/core/settle’); var buildURL = require(‘axios/lib/helpers/buildURL’); uni.request({ method: config.method.toUpperCase(), url:config.baseURL+buildURL(config.url,config.params,config.paramsSerializer), header: config.headers, data: config.data, dataType: config.dataType, responseType: config.responseType, sslVerify: config.sslVerify, complete: function complete(response) { console.log(“执行完成:”,response) response = { data: response.data, status: response.statusCode, errMsg: response.errMsg, header: response.header, config: config }; settle(resolve, reject, response); } }) }) }
axios 配置 adapter
设置自定义请求方法在axios配置中提供了 [adapter] 配置项使用该配置项目,我们可以设置属于自己的请求方法.
请求流程
req: 发起请求
reqContext: 包装请求上下文
adapter: 分发
dispath: 底层请求接口
server: 服务器
res: 响应处理
req-->reqContext-->adapter-->dispath-->server-->dispath-->adapter-->res
从流程上,我们大致知道 adapter 的调用位置,可以看到 adapter 是连接请求与响应的桥梁,
默认 adapter 在未配置 adapter 时, axios 将提供默认配置
// 默认配置
var defaults = {
adapter: getDefaultAdapter()
....
}
// 分发函数
function getDefaultAdapter() {
var adapter;
if(typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
// node环境下使用 node.http
adapter = require('./adapters/http');
} else if (typeof XMLHttpRequest !== 'undefined') {
// web 环境下使用 xhr
adapter = require('./adapters/xhr');
}
return adapter;
}
这里我们看到,adapter 主要根据环境不同,调用不同请求接口,并将数据返回给响应函数.
启示
整个请求过程是线性的,不存在路由分发的机制通过 adapter 我们可以直接控制请求及响应.使用 adapter 做 mock 这里只做实现的基本模式,在配置 adapter 可能遇到的问题
// mock数据路由,根据url 返回mock数据
const mockRouter = {...}
const http = Axios.create({
adapter: config =>{
// 判断是否存在mock数据
let has = mockRouter.has(config.url)
// 调用默认请求接口, 发送正常请求及返回
if(!data){
// 删除配置中的 adapter, 使用默认值
delete config.adapter
// 通过配置发起请求
return Axios(config)
}
// 模拟服务,返回mock数据
return new Promise((res, rej) =>{
const resInfo = {
data: mockRouter.getData(config)
status: 200,
statusText: 'OK'
}
// 调用响应函数
res(resInfo)
})
}
})
这里需要注意的是,在使用配置发起请求时,需要删除config中的 自定义adapter, 使用的aixos调用默认请求接口.否则将进入递归的死循环