代码改变世界

uniapp axios 真机运行报错errAxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environmen

2023-12-13 09:40  小罗世界  阅读(3993)  评论(0)    收藏  举报

我的项目中没有使用官方提供的uni.request,而是使用了axios,但遇到了一个问题是在我本地调试没问题,但真机运行时无法发送请求

uniapp浏览器运行axios请求可以正常调用接口,真机运行直接报错入下:errAxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build at utils/request.js:98

解决如下:

解决方案:配置axios适配器(axios-adapter-uniapp)

Using npm:

$ npm install axios-adapter-uniapp

Using yarn:

$ yarn add axios-adapter-uniapp

使用如下

import axios from 'axios'
import axiosAdapterUniapp from 'axios-adapter-uniapp'
 
const instance = axios.create({
  baseURL: 'URL.com',
  adapter: axiosAdapterUniapp
})
完整代码:
import axios from 'axios'
import axiosAdapterUniapp from 'axios-adapter-uniapp'

const api = "http://192.168.1.106:8090"
 
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const request = axios.create({
    // axios中请求配置有baseURL选项,表示请求URL公共部分
    // baseURL: process.env.VUE_APP_BASE_API,
    baseURL: api,
    adapter: axiosAdapterUniapp,
    // 超时(毫秒)
    timeout: 10000
})
 
//请求计数
let reqNum = 0
// request拦截器
request.interceptors.request.use(config => {
    // 在请求发出之前进行一些操作,每次发出请求就 reqNum++
    reqNum++
    // 是否需要设置 token
    const isToken = (config.headers || {}).isToken === false
    // 是否需要防止数据重复提交
    const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
    if (!isToken) {
        config.headers['uniapp'] = 'Y ' // 让每个请求携带自定义token 请根据实际情况自行修改
    }
    // get请求映射params参数
    if (config.method === 'get' && config.params) {
        // debugger
        // let params = {params:config.params}
        console.log(config);
        let url = config.url + '?' + config.params
        // url = url.slice(0, -1)
        config.params = {}
        config.url = url
    }
    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
        const requestObj = {
            url: config.url,
            data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
            time: new Date().getTime()
        }
 
    }
    return config
}, error => {
    console.log(error)
    Promise.reject(error)
})
 
// 响应拦截器
request.interceptors.response.use(res => {
        // console.log("axios响应拦截器")
        // debugger
        // 接受请求后 reqNum--,判断请求所有请求是否完成
        reqNum--
        if (reqNum <= 0) {
            // console.log('请求完毕')
        } else {
            // console.log('接口' + reqNum + '请求中')
        }
        // 未设置状态码则默认成功状态
        const code = res.data.code || "200"
        // 获取错误信息
        // const msg = errorCode[code] || res.data.msg || errorCode['default']
        // 二进制数据则直接返回
        // if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
        //     return res.data
        // }
        if (code === "401") {
            return Promise.reject('(401):请求要求身份验证。对于需要登录的网页,服务器可能返回此响应')
        } else if (code === "500") {
            uni.showToast({
                title: res.data.msg,
                duration: 2000
            });
 
            return Promise.reject(new Error(res.data.msg))
        } else if (code !== "200") {
            uni.showToast({
                title: res.data.msg,
                duration: 2000
            });
 
            return Promise.reject('error')
        } else {
            return res.data
        }
    },
    error => {
        console.log('err' + error)
        let {
            message
        } = error
        if (message == 'Network Error') {
            message = '后端接口连接异常'
        } else if (message.includes('timeout')) {
            message = '系统接口请求超时'
        } else if (message.includes('Request failed with status code')) {
            message = '系统接口' + message.substr(message.length - 3) + '异常'
        }
 
 
        uni.showModal({
            title: '提示',
            content: message,
            success: function(res) {
                if (res.confirm) {
                    console.log('用户点击确定');
                } else if (res.cancel) {
                    console.log('用户点击取消');
                }
            }
        });
 
 
        return Promise.reject(error)
    }
)
 
 
export default request
request.js

写接口文件:

import request from '@/utils/request'
 
/**
 * 授权登录
 * @param {*} data 
 */
export function getUserInfo(id) {
    return request({
        url: '/user/userInfo',
        method: 'get',
        // params: {},
        params: 'id='+id,
        // data
    })
}

export function login(data) {
    return request({
        url: '/user/login',
        method: 'post',
        params: {},
        data:data
    })
}
interface.js

测试写的登录界面及接口调用,完整代码,

<!-- 本示例未包含完整css,获取外链css请参考上文,在hello uni-app项目中查看 -->
<template>
    <view class="login">
        <view class="login-title" style="text-align: center;">
            用户登录
        </view>
        <view class="login-box" style="display: flex;flex-direction: column;align-items: center;">
            <view class="uni-form-item userinfo">
                <view class="title">用户名</view>
                <input class="uni-input" v-model="userName"  placeholder="请输入用户名" />
            </view>
            <view class="uni-form-item password">
                <view class="title">密码</view>
                <input class="uni-input" v-model="pwd" password type="text" placeholder="请输入密码" />
            </view>
            <view class="rst">
                <text>忘记密码</text>
                <text style="color: aqua;"> | </text>
                <text>注册</text>
            </view>
            <!-- <view class="btn"> -->
                <button class="btn" type="submit" @click="submit()">登录</button>
            <!-- </view> -->
            
        </view>
    </view>
</template>


<script>
import {login} from '../../utils/interface.js'
export default {
    data() {
        return {
            userName:null,
            pwd:null
        }
    },
    methods: {
        submit(){
            let userInfo = {
                username:this.userName,
                password:this.pwd,
            }
            // debugger
            login(userInfo).then(res=>{
                if(res.code==='200'){
                    uni.showToast({
                        title:"成功",
                        duration: 1000
                    })
                    uni.switchTab({
                        url:'/pages/index/index'
                    })
                }
            })
        }
    }
}
</script>


<style lang="scss">
.login{
    background-color: #9bdcce;
    height: 100vh;
    .login-title{
        font-size: 36rpx;
        font-family: '楷体';
        font-weight: bold;
        padding-top: 100rpx;
    }
    .login-box{
        background-color: white;
        width: 90%;
        margin:50rpx 0 0 5%;
        height: 70%;
        border-radius: 20rpx;
        justify-content: center;//众轴居中
        display: flex;
        flex-direction: column;
        align-items: center;//横轴居中
        .uni-form-item{
            &.userinfo{
                margin-bottom: 50rpx;
            }
            &.password{
                margin-bottom: 100rpx;
            }
            .uni-input{
                border-bottom:solid 2rpx black ;
            }
        }
        .btn{
                margin-top: 100rpx;
                width: 60%;
                background-color: #9bdcce;
            }
        
    }
}
</style>
login.vue
submit(){  //测试调用登录接口
            let userInfo = {
                username:this.userName,
                password:this.pwd,
            }
            // debugger
            login(userInfo).then(res=>{
                if(res.code==='200'){
                    uni.showToast({
                        title:"成功",
                        duration: 1000
                    })
                    uni.switchTab({
                        url:'/pages/index/index'
                    })
                }
            })
        }
    }