每日一问の二:uniapp中http请求能不能使用axios,如何兼容App?

每日一问の二:uniapp中http请求能不能使用axios,如何兼容App?

  1. 使用 npm install axios 命令安装 axios
  2. 新建一个文件夹再建一个 .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)
        }
    )
  3. main.js中放入这段自定义适配器的代码,就可以实现uniappapp和小程序开发中能使用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 我们可以直接控制请求及响应.使用 adaptermock 这里只做实现的基本模式,在配置 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调用默认请求接口.否则将进入递归的死循环

讨论数量: 0

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!