uni-app uni.chooseImage在微信内置浏览器时会走http拦截器事件

uni-app uni.chooseImage在微信内置浏览器时会走http拦截器事件

开发环境 版本号 项目创建方式
Windows 10 专业版 22H2 4.66 HBuilderX

示例代码:

uni.chooseImage({  
    sizeType: ['compressed'],  
    sourceType: sourceType,  
    success: ({  
        tempFilePaths,  
        tempFiles  
    }) => {  
        uni.showLoading({  
            title: '上传中...',  
            mask: true  
        })  
    }  
})

拦截器代码使用的是插件市场的luch-request 1.0.2 http请求插件

http.interceptor.response((response) => { /* 请求之后拦截器 */  
      uni.hideLoading();  
})

操作步骤:

调用uni.chooseImage

预期结果:

不走http拦截器事件

实际结果:

走了http拦截器事件

bug描述:

在开发H5公众号网页的时候遇到

在微信开发者工具浏览器内使用uni.chooseImage一切正常,逻辑符合我的预期

但是到真机上的时候,会发现uni.chooseImage会在选择完图片后走我的api请求拦截器(请求之后),我这边把上传图片uni.uploadFile去掉也会走拦截器,这肯定是不对的

我是如何发现这个问题的:首先我们先排除任何api请求事件,只使用uni.chooseImage,并在uni.chooseImage的success事件中调用uni.showLoading,会发现在微信开发者工具正常卡在showLoading动画,而我在拦截器上是有使用uni.hideLoading的不执行是正常的,但是在微信内置浏览器上同样调用uni.chooseImage他会在我选择完图片之后,立马调用了uni.hideLoading,导致加载动画提前结束,至于怎么知道我走了拦截器,我把拦截器的uni.hideLoading去掉,真机上就正常卡在showLoading事件了


更多关于uni-app uni.chooseImage在微信内置浏览器时会走http拦截器事件的实战教程也可以访问 https://www.itying.com/category-93-b0.html

11 回复

不在微信浏览器上,在chrome上运行是符合预期的吗?可以看一下控制台网络中是否有请求呢

更多关于uni-app uni.chooseImage在微信内置浏览器时会走http拦截器事件的实战教程也可以访问 https://www.itying.com/category-93-b0.html


刚试了,chrome上是不会的和微信开发者工具上一个效果,没有请求,只有在手机设备上直接使用微信内置浏览器访问才会有这个情况(微信APP内打开)

uni.chooseImage在真机会重新走一次onShow事件的问题,执行到我里面的请求了,别的浏览器环境不会这样走onShow,看看这算不算bug呢

如果不是,可以在uni.chooseImage文档里面说明一下,太搞了

应该是所有手机都会出现这种情况了,应该是我的问题,到手机相册那里再回来当然会出现走所有onShow事件,离谱

回复 m***@qq.com: 是在选择完之后,走到success或者fail之后,紧接着触发onshow是吗?

回复 DCloud_UNI_yuhe: 是的

开发者工具有这个效果吗?我这里测试没有复现你说的问题

工具不会,我是用区域网在手机上看才能看到效果,因为手机会先进相册,程序进入onHide,选择完回来又onShow了,但是在电脑上应用是不会被切走的,所以不会出现这种情况,只有手机会

这个不在手机上看到效果,容易逻辑乱掉,应该是没法避免了

这是一个已知的微信内置浏览器兼容性问题。uni.chooseImage在微信环境中选择图片时会触发XMLHttpRequest事件,导致HTTP拦截器被意外调用。

问题分析:

  1. 微信内置浏览器中,图片选择操作会创建临时的XHR请求来处理图片数据
  2. 这些内部请求同样会被luch-request等HTTP拦截器捕获
  3. 导致你在response拦截器中的uni.hideLoading()被提前执行

解决方案: 在拦截器中添加请求类型判断,过滤掉图片选择相关的内部请求:

http.interceptor.response((response) => {
    // 排除chooseImage产生的内部请求
    if (response.config?.url?.includes('chooseImage') || 
        response.config?.header?.['X-Requested-With'] === 'uni-chooseImage') {
        return response;
    }
    
    uni.hideLoading();
    // 其他拦截逻辑...
})

或者通过请求标记来区分:

// 在正常的API请求中添加标识
const config = {
    headers: {
        'X-Request-Type': 'api'
    }
}

// 在拦截器中判断
http.interceptor.response((response) => {
    if (response.config?.header?.['X-Request-Type'] !== 'api') {
        return response;
    }
    uni.hideLoading();
})
回到顶部