每日一问の二: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调用默认请求接口.否则将进入递归的死循环