uni-app 微信小程序web-view中 通过uni.navigateTo 跳转小程序页面偶尔失效,重新进入小程序后能跳转

发布于 1周前 作者 htzhanglong 来自 Uni-App

uni-app 微信小程序web-view中 通过uni.navigateTo 跳转小程序页面偶尔失效,重新进入小程序后能跳转

1. HTML 页面

<body>
<div id="app"></div>
</body>
<script type="text/javascript">
var userAgent = navigator.userAgent;
if (userAgent.indexOf('AlipayClient') > -1) {
// 支付宝小程序的 JS-SDK 防止 404 需要动态加载,如果不需要兼容支付宝小程序,则无需引用此 JS 文件。
document.writeln('<script src="https://appx/web-view.min.js">' + '</script>');
} else if (/QQ/i.test(userAgent) && /miniProgram/i.test(userAgent)) {
// QQ 小程序
document.write(
'<script type="text/javascript" src="https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"></script>'
);
} else if (/miniProgram/i.test(userAgent) && /micromessenger/i.test(userAgent)) {
// 微信小程序 JS-SDK 如果不需要兼容微信小程序,则无需引用此 JS 文件。
document.write('<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>');
} else if (/toutiaomicroapp/i.test(userAgent)) {
// 头条小程序 JS-SDK 如果不需要兼容头条小程序,则无需引用此 JS 文件。
document.write(
'<script type="text/javascript" src="https://s3.pstatp.com/toutiao/tmajssdk/jssdk-1.0.1.js"></script>');
} else if (/swan/i.test(userAgent)) {
// 百度小程序 JS-SDK 如果不需要兼容百度小程序,则无需引用此 JS 文件。
document.write(
'<script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.18.js"></script>'
);
} else if (/quickapp/i.test(userAgent)) {
// quickapp
document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"></script>');
}
</script>
<!-- uni 的 SDK -->
<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>  
</pre>

## 2. 跳转方法

```javascript
navigateTo(url, time = 0) {
this.url = isString(url) ? url : (`${url.url}?${dealUrlParams(url.query)}`)
this.time = time
this.navigation('navigateTo')
},
navigateBack(url) {
// eslint-disable-next-line no-undef
uni.navigateBack({
delta: 1
})
},
redirectTo(url, time = 0) {
this.url = isString(url) ? url : (`${url.url}?${dealUrlParams(url.query)}`)
this.time = time
this.navigation('redirectTo')
},
navigation(type) {
if (this.repeatTimer) {
return
}
// 防止重复点击
this.repeatTimer = setTimeout(() => {
this.repeatTimer = null
}, 500)
if (comparePlatform() === 'h5') {
setTimeout(() => {
window.parent.postMessage(JSON.stringify({ type: type, data: this.url }), '*')
}, this.time)
return
} else {
console.log(this.url)
setTimeout(() => {
// eslint-disable-next-line no-undef
uni[type]({
url: this.url
})
}, this.time)
}
},

1 回复

在uni-app中使用web-view组件嵌入网页时,确实可能会遇到通过uni.navigateTo跳转小程序页面偶尔失效的问题。这通常是由于web-view与小程序原生页面之间的上下文隔离或某些状态不一致导致的。以下是一个简化的代码示例,展示如何在web-view中触发跳转,并确保跳转逻辑尽可能可靠。

首先,确保你的web-view组件已正确配置并嵌入到小程序页面中:

<!-- pages/index/index.vue -->
<template>
  <view>
    <web-view src="https://your-webview-url.com"></web-view>
  </view>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {
    // 定义一个供web-view中js调用的方法(虽然这里不直接用于解决问题,但展示如何通信)
    handleJump() {
      uni.navigateTo({
        url: '/pages/target/target',
      });
    },
    // 注册一个全局事件监听器,用于接收web-view中的消息(推荐方式)
    mounted() {
      uni.$on('jump-event', this.handleJump);
    },
    beforeDestroy() {
      uni.$off('jump-event', this.handleJump);
    },
  },
};
</script>

然而,由于web-view中的页面是独立的,直接调用uni.navigateTo是不可能的。你需要通过postMessage API在web-view和小程序之间进行通信。

web-view中的网页代码(假设是HTML + JavaScript):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Web-view Page</title>
</head>
<body>
  <button onclick="triggerJump()">Jump to Mini Program Page</button>

  <script>
    function triggerJump() {
      if (window.WeixinJSBridge) {
        WeixinJSBridge.invoke('postMessage', { data: 'jump' }, '*');
      } else {
        document.addEventListener('WeixinJSBridgeReady', function () {
          WeixinJSBridge.invoke('postMessage', { data: 'jump' }, '*');
        }, false);
      }
    }
  </script>
</body>
</html>

在小程序页面接收消息并处理跳转:

// 在页面的onLoad或mounted生命周期中监听消息
onLoad() {
  uni.onMessage((res) => {
    if (res.data === 'jump') {
      uni.navigateTo({
        url: '/pages/target/target',
      });
    }
  });
},

注意,上述代码中的uni.onMessage监听器应放在能够持续监听消息的生命周期函数中,如onLoad或组件的mounted钩子(如果使用了Vue的生命周期)。同时,确保web-viewsrc是HTTPS协议,且域名已添加到小程序的业务域名中。

通过这种方式,你可以更可靠地从web-view触发小程序页面的跳转,减少偶尔失效的情况。

回到顶部