uni-app usa axios para enviar uma solicitação de execução para a ferramenta do desenvolvedor WeChat para relatar um erro Adaptador "http' não está disponível na compilação

Cenas

  • Recentemente, estou usando uni-app para desenvolver o terminal móvel H5. Como de costume, uso axios para enviar solicitações e fazer algumas operações globais de interceptação de solicitação e interceptação de resposta.

  • armazenamento de dados uni-app, desenvolvimento de componentes uni-ui, configuração de axios, vuex. O arquivo vue.config.js está configurado para operações entre domínios

  • Tudo funciona bem ao executar no Google Chrome, mas ao executar nas ferramentas do desenvolvedor WeChat, um erro é relatado, o Adaptador-adaptador não está disponível e a solicitação não pode ser enviada.

  • Por fim, após uma pesquisa na Internet, descobri que a resposta é a mesma, e o problema não foi resolvido, e demorou muito para resolver o problema.

Relatório de erro - o adaptador "http" não está disponível no buildat ObjectgetAdapter - a solicitação não é enviada

entenda por si mesmo

1. Muitas pessoas dizem que o axios não é compatível com o uni-app. Esse tipo de declaração é relativamente apressado. Na verdade, o uni-app também pode ser compatível com o axios após a modificação.

1. O Axios é baseado na camada de encapsulamento acima do AJax, e o princípio é enviar solicitações por meio de objetos minion

2. Nas ferramentas do desenvolvedor do WeChat, o ambiente do WeChat pode ter desativado o método de gravação de envio de solicitações na parte inferior do minion, resultando no não envio da solicitação e no erro não encontrado

3. A solução online é escrever um adaptador para axios no main.js ou request.js onde o axios é introduzido - ou alterar a versão

4. Esse método não resolve fundamentalmente o problema. Outro erro será relatado se a solicitação não for enviada. A URL de compilação está vazia e não pode ser encontrada.

Resolução de erro - se a solicitação não puder ser enviada, outro erro será reportado

Escreva um adaptador onde o axios é introduzido

// 解决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);
//    }
//   })
//  })
// }

resultado

 

Interpretação da cena atual

1. Por que não usar uni.request() fornecido pelo site oficial do aplicativo uni, porque ele não fornece interceptação de solicitação e interceptação de resposta, o que não é satisfatório.

2.uni-app usa axios para fazer solicitações

2.1 Ao executar o Google Chrome

  • Somos um ambiente node.js, precisamos configurar o endereço base node.js, interceptação de solicitação e interceptação de resposta em request.js como de costume

  • Defina variáveis ​​de ambiente globais no arquivo vue.config.js, e o arquivo global no site oficial do uni-app tem escrita de modelo

  • Por ser um navegador que precisa de cross-domain, também é necessário configurar cross-domain no vue.config.js

  • Por que usar o armazenamento de dados uni-app, porque o princípio de usar o armazenamento de dados uni-app é o armazenamento do navegador.

  • O armazenamento do navegador uni-app pode ser usado normalmente no Google Chrome, mas o armazenamento do navegador não pode ser usado nas ferramentas do desenvolvedor do WeChat, não é compatível

  • O arquivo vue.config.js define variáveis ​​globais - há exemplos no arquivo global no site oficial

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

2.2 Ao executar WeChat para ferramentas de desenvolvedor

  • Por ser uma ferramenta de desenvolvedor WeChat e um ambiente WeChat, não há domínio cruzado, o arquivo vue.config.js será inválido e o proxy será descartado

  • Como o ambiente WeChat não é compatível com axios, a solicitação não pode ser enviada e um erro será relatado - há uma solução abaixo

  • No ambiente WeChat, o endereço base em nosso arquivo request.js não pode ser escrito como uma variável global, mas deve ser escrito como uma string ip+port

solução correta

1. Substitua todos os axios, use o pacote de terceiros @escook/request-miniprogram semelhante ao axios

  • Você pode acessar o site oficial do npm para procurar este pacote e encontrará o uso detalhado deste pacote ao rolar para baixo.

  • Este método é usado apenas quando o problema do axios não pode ser resolvido, não o recomendamos aqui - há uma solução do axios abaixo

Código básico - crie requesthttp.js em utils e introduza-o em main.js (semelhante ao uso de axios - consulte os detalhes

// 按需导入 $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 a usar axios para ser compatível com o ambiente WeChat - com a ajuda de pacotes de terceiros

2.1 Precauções

  • Este método é testado pelo blogueiro e pode resolver o problema. Certifique-se de lê-lo passo a passo. Não se preocupe.

  • Às vezes, as ferramentas de desenvolvedor uni-app e WeChat apresentam bugs, lembre-se de fechar e reabrir a compilação

  • Outro pacote é baixado com base no axios, sem controlar a versão do axios, um arquivo createError.js precisa ser adicionado ao pacote do axios.

2.2 Implementação específica

2.2.1 Baixar axios-miniprogram-adapter no Hbuilder X

npm i axios-miniprogram-adapter

2.2.2 Visualize o pacote de arquivos lib/core/ sob o pacote axios no projeto node_model

 

2.2.3 Adicione a seguinte configuração no arquivo request.js

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 Ao executar de uni-app para ferramentas de desenvolvedor WeChat, o Hbuilder X relatará um erro

 

2.2.5 O relatório de erro significa que axios-miniprogram-adapter está referenciando o pacote em axios. Axios não possui este pacote e não pode encontrá-lo. Você pode clicar no relatório de erro abaixo para visualizá-lo na pasta correspondente

2.2.6 Crie um pacote createError.js em axios/lib/core para axios-miniprogram-adapter para resolver o problema

  • Venha para este diretório para criar o arquivo createError.js

  • Copie o conteúdo do arquivo AxiosError.js diretamente para o arquivo createError.js

 

2.2.7 Execute novamente o projeto para a ferramenta de desenvolvedor WeChat no Hbuilder X e descubra que não há erro, axios podem ser usados ​​e a solicitação é enviada

 

2.2.8 código completo request.js - apenas para referência, é melhor não copiar

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

Resumir:

Após as operações acima, o axios pode ser compatível com ferramentas de desenvolvedor uni-app e satélite. Só precisamos mudar a configuração de endereço base ao enviar para o navegador e ferramentas de desenvolvedor WeChat, e ambas as extremidades podem ser adaptadas.


Após esse processo, acredito que você também tenha uma impressão profunda preliminar no uni-app usando axios para enviar uma solicitação de execução para a ferramenta de desenvolvedor WeChat para relatar um erro Adaptador "http' não está disponível na compilação, mas no desenvolvimento real encontramos A situação é definitivamente diferente, então temos que entender seus princípios e manter o mesmo princípio. Vamos, vença os trabalhadores!

Por favor, aponte quaisquer deficiências, obrigado -- Fengguowuhen

Acho que você gosta

Origin blog.csdn.net/weixin_53579656/article/details/131196834
Recomendado
Clasificación