uni-app uses axios to send a request to run to the WeChat developer tool to report an error Adapter "http' is not available in the build

Scenes

  • Recently, I am using uni-app to develop H5 mobile terminal. As usual, I use axios to send requests, and do some global request interception and response interception operations.

  • uni-app data storage, uni-ui component development, configuration of axios, vuex. The vue.config.js file is configured for cross-domain operations

  • Everything works fine when running on Google Chrome, but when running on WeChat developer tools, an error is reported, the Adapter-adapter is unavailable, and the request cannot be sent.

  • Finally, after a search on the Internet, I found that the answer is the same, and the problem has not been solved, and it took a long time to solve the problem.

Error report - the adapter "http" is not available in buildat ObjectgetAdapter - the request is not sent at all

understand by yourself

1. Many people say that axios is not compatible with uni-app. This kind of statement is relatively hasty. In fact, uni-app can also be compatible with axios after modification.

1. Axios is based on the encapsulation layer above AJax, and the principle is to send requests through minion objects

2. In the WeChat developer tools, the WeChat environment may have disabled the writing method of sending requests at the bottom of the minion, resulting in the request not being sent out, and the error cannot be found

3. The online solution is to write an adapter for axios in the main.js or request.js where axios is introduced - or change the version

4. This method does not fundamentally solve the problem. Another error will be reported if the request is not sent out. The build URL is empty and cannot be found.

Error resolution - if the request cannot be sent out, another error will be reported

Write an adapter where axios is introduced

// 解决uni-app Adapter为空问题
// axios.defaults.adapter = function(config) {
//  return new Promise((resolve, reject) => {
//   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) {
//     response = {
//      data: response.data,
//      status: response.statusCode,
//      errMsg: response.errMsg,
//      header: response.header,
//      config: config
//     };
​
//     settle(resolve, reject, response);
//    }
//   })
//  })
// }

result

 

Interpretation of the current scene

1. Why not use uni.request() provided by uni-app official website, because it does not provide request interception and response interception, which is not satisfactory.

2.uni-app uses axios to make requests

2.1 When running Google Chrome

  • We are a node.js environment, we need to configure the node.js base address, request interception, and response interception in request.js as usual

  • Set global environment variables in the vue.config.js file, and the global file on the uni-app official website has template writing

  • Because it is a browser that needs cross-domain, it is also necessary to configure cross-domain in vue.config.js

  • Why use uni-app data storage, because the principle of using uni-app data storage is browser storage.

  • The uni-app browser storage can be used normally in Google Chrome, but the browser storage cannot be used in WeChat developer tools, it is not compatible

  • The vue.config.js file sets global variables - there are examples in the global file on the official website

chainWebpack: config => {
    config
      .plugin('define')
      .tap(args => {
        args[0]['process.env'].VUE_APP_BASE_API = '"/dev-api"'
        return args
      })
  }

2.2 When running WeChat to developer tools

  • Because it is a WeChat developer tool and WeChat environment, there is no cross-domain, the vue.config.js file will be invalid, and the proxy will be discarded

  • Because the WeChat environment is not compatible with axios, the request cannot be sent out, and an error will be reported-there is a solution below

  • In the WeChat environment, the base address in our request.js file cannot be written as a global variable, but should be written as a string ip+port

correct solution

1. Replace all axios, use the third-party package @escook/request-miniprogram similar to axios

  • You can go to the npm official website to search for this package, and you will find detailed usage of this package when you scroll down.

  • This method is only used when the axios problem cannot be solved, we do not recommend it here - there is axios solution below

Basic code - build requesthttp.js under utils and introduce it in main.js (similar to axios use - see for details

// 按需导入 $http 请求对象
import { $http } from '@escook/request-miniprogram'
​
// 将按需导入的 $http 挂载到 wx 顶级对象之上,方便全局调用
// wx这个东西是微信小程序里的顶级对象,也就是说所有页面都可以访问wx这个对象
// 所以我所有地方就可以用 wx.$http访问到请求对象了
// wx.$http = $http
​
// 设置基地址
$http.baseUrl = 'https://api-hmugo-web.itheima.net/api/public/v1/'
// process.env.VUE_APP_BASE_API
​
// 在 uni-app 项目中,可以把 $http 挂载到 uni 顶级对象之上,方便全局调用
// 小程序里wx是顶级对象,但是在uniapp中,uni才是顶级对象
uni.$http = $http
​
// 请求开始之前做一些事情
// 因为咱们是uniapp项目,顶级对象不叫wx,叫uni,记得把wx这个改成uni
$http.beforeRequest = function (options) {
  uni.showLoading({
    title: '数据加载中...',
  })
}
​
// 请求完成之后做一些事情
$http.afterRequest = function () {
  uni.hideLoading()
}

2. Continue to use axios to be compatible with the WeChat environment - with the help of third-party packages

2.1 Precautions

  • This method is tried by the blogger, and it can solve the problem. Be sure to read it step by step. Don’t worry.

  • Sometimes uni-app and WeChat developer tools will have bugs, remember to close and reopen the compilation

  • Another package is downloaded based on axios, without controlling the axios version, a createError.js file needs to be added to the axios package.

2.2 Specific implementation

2.2.1 Download axios-miniprogram-adapter in Hbuilder X

npm i axios-miniprogram-adapter

2.2.2 View the lib/core/ file package under the axios package in the project node_model

 

2.2.3 Add the following configuration under the request.js file

import adapter from 'axios-miniprogram-adapter'
​
// 设置基地址
const request = axios.create({
    // 运行到浏览器时,把这一行注释回来,VUE_APP_BASE_API是在vue.config.js中配置的,官网有
    // baseURL: process.env.VUE_APP_BASE_API,
    // 运行到浏览器时下面一行注释掉
    baseURL: 'http://127.0.0.1:8800',
    // 在微信开发者工具环境中,axios,http是发不出去的,没有跨域,vue.config.js文件也是无效的
    // 基于axios-miniprogram-adapter包给axios中添加一个适配器
    // 运行到浏览器时,下面一行注释掉,axios时可以在浏览器中正常使用的,不需要适配器
    adapter: adapter,
})

2.2.4 When running from uni-app to WeChat developer tools, Hbuilder X will report an error

 

2.2.5 The error report means that axios-miniprogram-adapter is referencing the package in axios. Axios lacks this package and cannot find it. You can click the error report below to view it in the corresponding folder

2.2.6 Create a createError.js package in axios/lib/core for axios-miniprogram-adapter to solve the problem

  • Come to this directory to create createError.js file

  • Copy the contents of the AxiosError.js file directly to the createError.js file

 

2.2.7 Re-run the project to the WeChat developer tool in Hbuilder X and find that there is no error, axios can be used, and the request is sent

 

2.2.8 request.js complete code - for reference only, it is best not to copy

import axios from 'axios'
​
import adapter from 'axios-miniprogram-adapter'
// 引入vuex
import store from '@/store'
​
// 解决uni-app Adapter为空问题-不可行解决不了
// axios.defaults.adapter = function(config) {
//  return new Promise((resolve, reject) => {
//   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) {
//     response = {
//      data: response.data,
//      status: response.statusCode,
//      errMsg: response.errMsg,
//      header: response.header,
//      config: config
//     };
​
//     settle(resolve, reject, response);
//    }
//   })
//  })
// }
​
// 设置基地址
const request = axios.create({
    // 运行到浏览器时,把这一行注释回来,VUE_APP_BASE_API是在vue.config.js中配置的,官网有
    // baseURL: process.env.VUE_APP_BASE_API,
    // 运行到浏览器时下面一行注释掉
    baseURL: 'http://127.0.0.1:8800',
    // 在微信开发者工具环境中,axios,http是发不出去的,没有跨域,vue.config.js文件也是无效的
    // 基于axios-miniprogram-adapter包给axios中添加一个适配器
    // 运行到浏览器时,下面一行注释掉,axios时可以在浏览器中正常使用的,不需要适配器
    adapter: adapter,
})
​
// 解决UNI-app上adapter is not a function问题
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) {
                response = {
                    data: response.data,
                    status: response.statusCode,
                    errMsg: response.errMsg,
                    header: response.header,
                    config: config
                };
​
                settle(resolve, reject, response);
            }
        })
    })
}
​
​
// 请求拦截
request.interceptors.request.use(
    config => {
        console.log('store.getters.token', store.getters.token);
        if (store.getters.token) {
            console.log('执行了');
            // config.headers['token'] = getToken()
            // config.headers['tenant-id'] = getuserId()
            // 建议使用uni-app数据同步存储,在谷歌浏览器可以用,但是谷歌浏览器储存在微信开发者工具用了
            config.headers['token'] = uni.getStorageSync('token')
            config.headers['tenant-id'] = uni.getStorageSync('tenant-id')
        }
        return config
    },
    error => {
        return Promise.reject(error)
    }
)
​
​
// 响应拦截
request.interceptors.response.use(
    res => {
        const data = res.data
        if (data.code === 200) {
            // 如果响应成功,则正常给他返回数据
            return data
        } else {
            uni.$showToast(data.message)
            return Promise.reject(new Error(data.message))
        }
    },
    // 响应错误的代码写这里
    async error => {
        // 打印错误拦截的信息
        console.log('响应拦截error', error)
        // error.response 这个是浏览器语法错误返回信息
        // error.response.data 这个是接口返回错误信息 固定写法 看打印
        if (error.response && error.response.data) {
            // token失效携带页面参数返回登录页
            if (error.response.status === 401) {
                // vuex退出登录方法
            } else {
                console.log(error.response.data.message);
                uni.$showToast('请求错误')
            }
        }
        return Promise.reject(error)
    }
)
​
// 把对象暴露出去
export default request

Summarize:

After the above operations, axios can be compatible with uni-app and satellite developer tools. We only need to switch the base address configuration when shipping to the browser and WeChat developer tools, and both ends can be adapted.


After this process, I believe you also have a preliminary deep impression on uni-app using axios to send a request to run to the WeChat developer tool to report an error Adapter "http' is not available in the build, but in the actual development we encountered The situation is definitely different, so we have to understand its principles and keep the same principle. Come on, beat the workers!

Please point out any deficiencies, thank you -- Fengguowuhen

Guess you like

Origin blog.csdn.net/weixin_53579656/article/details/131196834