Uniapp中嵌入H5( uniapp开发的H5),并且在H5中跳转到APP的指定页面

原生H5跳转uniapp开发的app方式:

1.在APP中使用web-view嵌入H5页面使用web-view组件实现
<template>
	<view>
		<web-view src="https://uniapp.dcloud.net.cn/component/web-view.html"></web-view>
	</view>
</template>

2.在H5项目引入webview.js

<!-- 需要把 uni.webview.1.5.4.js 下载到自己的服务器 -->   导入web-view 的SDK
    <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
    

 3.调用方法跳转至app 内部的页面的关键方法 uni.reLaunch

uni.reLaunch({
                  url: '/pages/tabBar/component/component'
                });

4.跳转方式:

<!-- uni 的 SDK -->
    <!-- 需要把 uni.webview.1.5.4.js 下载到自己的服务器 -->
    <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
    <script type="text/javascript">
      // 待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。 
      //H5端与app端通信
      document.addEventListener('UniAppJSBridgeReady', function() {
        uni.postMessage({
            data: {
                action: 'message'
            }
        });
        uni.getEnv(function(res) {
            console.log('当前环境:' + JSON.stringify(res));
        });

        document.querySelector('.btn-list').addEventListener('click', function(evt) {
          var target = evt.target;
          if (target.tagName === 'BUTTON') {
            var action = target.getAttribute('data-action');
            switch (action) {
              case 'switchTab':
                uni.switchTab({
                  url: '/pages/tabBar/API/API'
                });
                break;
              case 'reLaunch':
                uni.reLaunch({
                  url: '/pages/tabBar/component/component'
                });
                break;
              case 'navigateBack':
                uni.navigateBack({
                  delta: 1
                });
                break;
              default:
                uni[action]({
                  url: '/pages/component/button/button'
                });
                break;
            }
          }
        });
        document.getElementById('postMessage').addEventListener('click', function() {
          uni.postMessage({
            data: {
              action: 'message'
            }
          });
        });
      });
    </script>

上面的跳转方式可以解决APP嵌入原生H5页面跳转回APP的问题,但是使用uniapp开发的H5就会失效,在uniapp开发H5页面使用 uni.reLaunch 只能跳转到H5项目本地的页面。

uniapp开发H5跳转方式:

1.在H5项目里引入 web-view.js:

通过官网链接下载 web-view.js文件(下载链接,打开链接右键另存为下载链接,),放到项目的static/js文件中

2.在main.js中引入

import App from './App'
import webView from './static/js/uni.webview.1.5.2.js'
....

3.使用方式:

				// #ifdef APP-PLUS
				uni.webView.postMessage({
					data: {
						action: 'uni-app',
					}
				});
				uni.webView.reLaunch({
					url: '/pages/tabBar/component/component'
				});

区别在于 uniapp开发的H5要在uni前面加上 webView

项目中使用的完整代码创建示例:

 

  1. 在app项目添加webview文件夹添加gridWebview.vue文件。代码如下
<template>
	<view>
		<web-view :src="src" @message="getMessage" ></web-view>
	</view>
</template>



<script>
	export default {
		data() {
			return {
				src: '',
			}
		},
		computed: {
			token() {
				return this.$store.state.login.token || ''
			},
			roles() {
				return this.$store.state.login.roles || ''
			},
			userInfo(){
				return this.$store.state.login.userInfo || ''
			}
		},
		onLoad(opt) {
			console.log(opt)
            //拼接所需参数
			this.title = opt.title
			this.src = opt.src
			 + (opt.src.includes('?') ? '&' : '?') 
			 + (this.token.length>0 ? 'token=' + this.token : '') 
			 + (this.userInfo.phone.length>0 ?`&phone=${this.userInfo.phone}` :'' )
			 + (this.userInfo.userId.length>0 ?`&userId=${this.userInfo.userId}` :'' )
			 + (this.userInfo.username.length>0 ?`&username=${this.userInfo.username}` :'' )
			 + (opt.data?`&data=${opt.data}` :'' )
			 + (opt.cityid?`&cityid=${opt.cityid}` :'' )
		},
		onShow() {
			// #ifdef APP-PLUS
            设置webview显示时顶部丢失问题
			var height = 0; //定义动态的高度变量,如高度为定值,可以直接写
			uni.getSystemInfo({
				//成功获取的回调函数,返回值为系统信息
				success: (sysinfo) => {
					height = sysinfo.windowHeight -
						40; //自行修改,自己需要的高度 此处如底部有其他内容,可以直接---(-50)这种,如果不减,页面会下沉,看不到底部导航栏
				},
				complete: () => {}
			});
			var currentWebview = this.$scope.$getAppWebview(); //获取当前web-view
			setTimeout(function() {
				var wv = currentWebview.children()[0];
				wv.setStyle({ //设置web-view距离顶部的距离以及自己的高度,单位为px
					top: 40, //此处是距离顶部的高度,应该是你页面的头部
					height: height, //webview的高度
					scalable: false, //webview的页面是否可以缩放,双指放大缩小,
				})
			}, 500); //如页面初始化调用需要写延迟
			// #endif
		},
		methods: {
			customBack() {
				// 在Webview页面中调用uni.navigateBack()  
				uni.navigateBack();
			},
			getMessage(event) {  //在H5端使用通信返回App端
				console.log(event, '0000000000000000000000000')
				if (event.detail.data[0].action == 'uni-app') {
					uni.navigateBack();
				}
			}

		},

	}
</script>

2. app跳转H5使用如下方法:

//跳转到对应的webview页面并传入url和其他参数
uni.navigateTo({
						url: item.url.startsWith('http') ? `/pages/webview/gridWebview?title=${item.name}&src=${item.url}` : item.url
					})

3.H5返回app使用如下方法:

app.vue页面需要引入uni.webview.1.5.2.js文件 (目前此方法只能在真机上返回,H5上目前点击无效)

<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script> 
onLaunch: function() {
			this.initScript()
			console.log('App Launch')
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		},
		methods: {
			initScript() {
				var script = document.createElement('script');
				script.type = "text/javascript";
				script.async = true;
				script.src = "./static/js/uni.webview.1.5.2.js";
				document.head.appendChild(script);
				console.log(wx, "wx");
			}
		}

在需要返回的页面添加返回方法:

goBack() {
				console.log('0000000', uni, )
				uni.webView.postMessage({
					data: {
						action: 'uni-app', //可自己随意定义,需要与app中接收通信的方法对应
					}
				});
}

官方H5代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <title>网络网页</title>
    <style type="text/css">
      .btn {
        display: block;
        margin: 20px auto;
        padding: 5px;
        background-color: #007aff;
        border: 0;
        color: #ffffff;
        height: 40px;
        width: 200px;
      }

      .btn-red {
        background-color: #dd524d;
      }

      .btn-yellow {
        background-color: #f0ad4e;
      }

      .desc {
        padding: 10px;
        color: #999999;
      }

      .post-message-section {
        visibility: hidden;
      }
    </style>
  </head>
  <body>
    <p class="desc">web-view 组件加载网络 html 示例。点击下列按钮,跳转至其它页面。</p>
    <div class="btn-list">
      <button class="btn" type="button" data-action="navigateTo">navigateTo</button>
      <button class="btn" type="button" data-action="redirectTo">redirectTo</button>
      <button class="btn" type="button" data-action="navigateBack">navigateBack</button>
      <button class="btn" type="button" data-action="reLaunch">reLaunch</button>
      <button class="btn" type="button" data-action="switchTab">switchTab</button>
    </div>
    <div class="post-message-section">
      <p class="desc">网页向应用发送消息,注意:小程序端应用会在此页面后退时接收到消息。</p>
      <div class="btn-list">
        <button class="btn btn-red" type="button" id="postMessage">postMessage</button>
      </div>
    </div>
    <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>');
      }
      if (!/toutiaomicroapp/i.test(userAgent)) {
        document.querySelector('.post-message-section').style.visibility = 'visible';
      }
    </script>

//跳转方式,下面一部分代码
<!-- uni 的 SDK -->
    <!-- 需要把 uni.webview.1.5.4.js 下载到自己的服务器 -->
    <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
    <script type="text/javascript">
      // 待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。 
      // H5端与app端通信
      document.addEventListener('UniAppJSBridgeReady', function() {
        uni.postMessage({
            data: {
                action: 'message'
            }
        });
        uni.getEnv(function(res) {
            console.log('当前环境:' + JSON.stringify(res));
        });

        document.querySelector('.btn-list').addEventListener('click', function(evt) {
          var target = evt.target;
          if (target.tagName === 'BUTTON') {
            var action = target.getAttribute('data-action');
            switch (action) {
              case 'switchTab':
                uni.switchTab({
                  url: '/pages/tabBar/API/API'
                });
                break;
              case 'reLaunch':
                uni.reLaunch({
                  url: '/pages/tabBar/component/component'
                });
                break;
              case 'navigateBack':
                uni.navigateBack({
                  delta: 1
                });
                break;
              default:
                uni[action]({
                  url: '/pages/component/button/button'
                });
                break;
            }
          }
        });
        document.getElementById('postMessage').addEventListener('click', function() {
          uni.postMessage({
            data: {
              action: 'message'
            }
          });
        });
      });
    </script>
    
  </body>
</html>


<think>我们将在UniApp嵌入H5页面,需要处理多端兼容(H5App、小程序)。核心思路是使用条件编译和不同的组件: - H5端:直接使用`<iframe>`标签 - App端:使用`<web-view>`组件 - 小程序端:微信小程序可使用`<web-view>`(需配置业务域名),但注意有使用限制;其他小程序可能不支持或部分支持。 由于小程序对`<web-view>`有较多限制(如需要配置业务域名、每个页面只能有一个web-view等),这里我们主要考虑H5App端,小程序端可能需要额外处理(例如提示用户跳转或使用其他方式)。 以下是一个完整的实现示例:</think>### 在 UniApp嵌入 H5 页面的完整解决方案 #### 核心实现代码(支持 H5/App/小程序三端) ```html <template> <!-- 多平台兼容方案 --> <view class="h5-container"> <!-- H5平台使用iframe --> <!-- #ifdef H5 --> <iframe :src="h5Url" class="h5-frame" @load="onIframeLoad" allowfullscreen ></iframe> <!-- #endif --> <!-- App平台使用web-view --> <!-- #ifdef APP-PLUS --> <web-view :src="appUrl" :style="{ height: webviewHeight + 'px' }" @message="onWebviewMessage" ></web-view> <!-- #endif --> <!-- 小程序平台处理 --> <!-- #ifdef MP-WEIXIN --> <view v-if="showMiniProgramTip" class="tip-box"> <text>当前小程序无法直接嵌入H5页面</text> <button @click="openH5InBrowser">在浏览器中打开</button> </view> <!-- #endif --> </view> </template> <script> export default { data() { return { h5Url: "https://example.com", // 要嵌入H5地址 appUrl: "", // App端处理后的URL webviewHeight: 500, // App端高度 showMiniProgramTip: true // 小程序提示 }; }, mounted() { this.initWebview(); // App端动态计算高度 // #ifdef APP-PLUS uni.getSystemInfo({ success: (res) => { this.webviewHeight = res.windowHeight - 50; // 减去顶部导航栏高度 } }); // #endif }, methods: { initWebview() { // App端特殊处理:解决iOS白屏问题 // #ifdef APP-PLUS const timestamp = new Date().getTime(); this.appUrl = `${this.h5Url}?timestamp=${timestamp}`; // #endif }, // iframe加载完成事件 onIframeLoad() { console.log("H5页面加载完成"); // 可以在这里与H5页面通信 }, // web-view消息接收 onWebviewMessage(e) { console.log("收到H5消息:", e.detail.data); // 处理从H5页面发来的消息 }, // 小程序打开外部浏览器 openH5InBrowser() { uni.setClipboardData({ data: this.h5Url, success: () => { uni.showModal({ title: "提示", content: "链接已复制,请在浏览器中打开", showCancel: false }); } }); } } } </script> <style> .h5-container { position: relative; height: 100vh; } /* 通用H5容器样式 */ .h5-frame { width: 100%; height: 100%; border: none; } /* App端web-view样式 */ /* #ifdef APP-PLUS */ web-view { width: 100%; } /* #endif */ /* 小程序提示样式 */ /* #ifdef MP-WEIXIN */ .tip-box { padding: 20px; text-align: center; } .tip-box text { display: block; margin-bottom: 15px; color: #666; } /* #endif */ ``` ### 关键配置说明 1. **多平台适配策略** | **平台** | **技术方案** | **注意事项** | |----------|--------------|--------------| | **H5** | 使用 `<iframe>` | 支持完整交互功能 | | **App** | 使用 `<web-view>` | 需配置域名白名单 | | **微信小程序** | 提示跳转浏览器 | 小程序限制较多 | 2. **App端必需配置** 在 `manifest.json` 中添加: ```json "app-plus": { "webview": { "domStorage": true, // 启用本地存储 "database": true, // 启用数据库 "userAgent": "UniApp H5 Container" // 自定义UA } } ``` 3. **解决iOS白屏问题** ```javascript // 添加时间戳参数避免缓存问题 const timestamp = new Date().getTime(); this.appUrl = `${this.h5Url}?timestamp=${timestamp}`; ``` ### 高级功能实现 #### 1. UniAppH5页面双向通信 ```javascript // UniAppH5 发送消息 sendToH5(message) { // #ifdef H5 const iframe = document.querySelector('.h5-frame'); iframe.contentWindow.postMessage(message, '*'); // #endif // #ifdef APP-PLUS const pages = getCurrentPages(); const page = pages[pages.length - 1]; const webview = page.$getAppWebview(); webview.evalJS(`receiveFromApp(${JSON.stringify(message)})`); // #endif } // H5页面中接收消息 window.addEventListener('message', (event) => { console.log('收到UniApp消息:', event.data); }); ``` #### 2. 处理H5页面导航 ```javascript // 监听H5内部导航变化 // #ifdef APP-PLUS onWebviewNavigation(event) { const currentUrl = event.url; if (!currentUrl.includes('allowed-domain.com')) { // 阻止访问非白名单域名 plus.webview.currentWebview().stop(); uni.showToast({ title: '禁止访问该域名', icon: 'none' }); } } // #endif ``` ### 常见问题解决方案 1. **App页面空白** - 原因:域名未加入白名单 - 解决:在项目根目录创建 `common` 文件夹,添加 `verify.html` 文件(内容可为空) 2. **H5页面适配问题** ```html <!--H5页面头部添加 --> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> ``` 3. **跨域通信问题** -H5页面设置: ```javascript document.domain = "your-main-domain.com"; ``` > **性能优化建议**: > App端使用 `subNVue` 原生子窗体提升渲染性能: > ```javascript > const subNvue = uni.getSubNVueById('webview'); > subNvue.show('slide-in-bottom', 300); > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值