在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面通讯

uni-app的web-view组件,支持加载远程网页,在app环境下,还支持加载本地HTML页面。

在web-view加载页面中,会涉及wx、plus、uni等对象的使用。

  • 在小程序下使用wx的api,需要引入微信提供的https://res.wx.qq.com/open/js/jweixin-1.4.0.js。
  • 在app下默认有plus对象,不需要引入js文件。
  • 不管是在小程序下还是在app下,使用uni的api,需要引入https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js
\n

本文会详述在webview里的uni对象的使用方式,以及和vue页面的通讯方式。

HBuilderX 1.0.0 版本开始,uni-app 支持在 web-view 中调用 uni 的 API。

引用依赖的文件

\n

在 web-view 加载的 HTML 中调用 uni 的 API,需要在 HTML 中引用必要的 JS-SDK。

<!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->
<script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<!-- uni 的 SDK,必须引用。 -->
<script type="text/javascript" src="//js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js"></script>
\n

Tips

  • 这些 JS 文件是在 web-view 加载的那个 HTML 文件中引用的,而不是 uni-app 项目中的文件。
  • 如果不考虑微信小程序,则无需引入微信的 JS-SDK。
  • 两个文件同时引入时,注意引入的顺序,微信的需要在前。
\n

调用的时机

\n

在引用依赖的文件后,需要在 HTML 中监听 UniAppJSBridgeReady 事件触发后,才能安全调用 uni 的 API。

document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
});
\n

页面跳转

\n

支持调用所有的 uni 路由方法,可以实现从 HTML 重新跳转回应用内的页面。

在 UniAppJSBridgeReady 后,调用路由方法跳转到应用内的页面。

document.addEventListener('UniAppJSBridgeReady', function() {
document.querySelector('.btn-list').addEventListener('click', function(evt) {
var target = evt.target;
if (target.tagName === 'BUTTON') {
var action = target.getAttribute('data-action');
if(action === 'navigateTo') {
uni.navigateTo({
url: '/pages/component/button/button'
});
}
}
});
});
\n

发送消息

\n

可以通过 uni.postMessage 在 HTML 中向应用发送消息。要实现此功能,需要完成以下两步工作。

监听 web-view 的 message 事件

\n

监听 web-view 组件的 message 事件,然后在事件回调的 event.detail.data 中接收传递过来的消息。

<template>
<view>
<web-view src="http://192.168.1.1:3000/test.html" @message="handleMessage"></web-view>
</view>
</template>

<script>
export default {
methods: {
handleMessage(evt) {
console.log('接收到的消息:' + JSON.stringify(evt.detail.data));
}
}
}
</script>
\n

从 HTML 向应用发送消息

\n

uni.postMessage 中的参数格式,必须是 data: {}。也就是说,传递的消息信息必须在 data 这个对象中。

document.addEventListener('UniAppJSBridgeReady', function() {
uni.postMessage({
data: {
action: 'postMessage'
}
});
});
\n

每次执行 postMessage 后,传递的消息会以数组的形式存放。因此,在 web-view 的 message 事件回调中,接收到的 event.detail.data 的值是一个数组。

获取当前环境信息

\n

HTML 在不同的环境下,可能需要执行不同的操作或传递不同的消息。可以通过 uni.getEnv() 方法,来获取当前的环境信息。

document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
if (res.plus) {
console.log('当前环境为【5+App】');
} else if (res.miniprogram) {
console.log('当前环境为【微信小程序】');
}
});
});
\n

本地 HTML

\n

自 HBuilderX v1.1.0 起,在 5+App 平台下 web-view 支持加载应用内的 HTML 资源。
本地的 HTML 资源,必须存放在规定的目录下,即 uni-app 项目->hybrid->html 目录。

├─common    
├─components
├─hybrid
│ └─html
│ test.html
├─pages
├─static
│ App.vue
│ main.js
│ manifest.json
│ pages.json
\n

与 html 文件相关的 css、js 等本地资源,同样放在这个 hybrid->html 目录下。
这个hybrid目录不会被编译器编译,所以这里的不能放vue文件,而其他目录也不能放本地HTML文件。
未来hybrid目录还会支持其他语言在uni-app的中的混合使用。

注意:在本地 HTML 中引入网络资源时,必须补全协议。比如:https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js

运行体验

\n

示例中 web-view 加载的是一个本机的测试地址,这个测试 HTML 见附件。

  • 加载网络地址的话,需要在本机启动一个服务将此 HTML 放进去,然后修改 hello uni-app 中的 web-view 例子的 src 地址为可访问的局域网地址。
  • 如果是加载本地 HTML 的话,就直接新建目录将此 HTML 放进去,然后修改 web-view 的 src 为 /hybrid/html/test.html 即可。

  • 参考文档:web-view

\n

web-view组件在app中的窗体关系和plus.webview操作方式

\n

uni-app的vue页面本身是一个webview,vue页面里的web-view组件,其实是一个子webview。
但一个vue页面不能放多个web-view组件,这个组件默认是全屏的(不会覆盖原生头和原生导航)。
使用plus代码获得当前webview的对象后(参考此文https://ask.dcloud.net.cn/article/35036),再获取子webview,其实也可以得到web-view组件所对应的plus的webview对象,进而再使用plus.webview的丰富api。
获取子webview时注意时机,获取方法执行太早可能获取不到。


6 分享 关注
DCloud_MUI_Neil jack_zheng xiangdeshan_120@sina.com bachest 466509589@qq.com SnoopyChen
hcy.php@qq.com

hcy.php@qq.com

uni.postMessage({
data: {
action: editor.txt.html();//富文本内容
}
});

请教一下大神,传输数据回去,进入这个页面 改变了内容 传不回去是怎么回事,只能传回去页面加载出来的初始内容,在页面上修改内容后新内容传不回去,怎么解决啊。
0 赞 2019-01-09 15:53
1206188300@qq.com

1206188300@qq.com

关于获取vue页面中的web-view组件对象,需要设置延时才能正常的获取到该对象。一般手机500mm可以获取到了,但是今天测试华为手机,要设置1s才能获取到该web-view对象。比如:小米,一加手机等500mm能正常获取,但是华为就要1s。延时时间是和手机配置什么的有关吗?那设置这个延时时间有什么标准吗?
0 赞 2018-12-26 18:00
风雅

风雅

怎么刷新页面呢?最好头部右侧增加刷新按钮
0 赞 2018-12-13 09:11
657917826@qq.com

657917826@qq.com

下载最近HBuilderX,webview请求的页面无法打开,什么原因????
0 赞 2018-11-29 15:48
DCloud_客服_Trust

DCloud_客服_Trust 回复 余红杰

http://uniapp.dcloud.io/component/web-view
网页向应用 postMessage 时,会在特定时机(后退、组件销毁、分享)触发并收到消息。
0 赞 2018-10-30 13:49
余红杰

余红杰

不对,实测是这样:
如果成功调用navigateback或者redirect事件则会收到message,这是什么原因呢
0 赞 2018-10-30 13:28
余红杰

余红杰

Tue Oct 30 2018 11:29:37 GMT+0800 (CST) 事件警告
11:29:39.673 OnWebviewEvent: __DOMReady, WebviewId: 1 not found
11:29:39.694 console.groupEnd
这是唯一的警告,难道是因为这个?
0 赞 2018-10-30 11:31
余红杰

余红杰

html页面给vue发送消息怎么没反应啊?可以使用Uni跳转页面,但是message就不行
0 赞 2018-10-30 11:30
DCloud_客服_Trust

DCloud_客服_Trust 回复 余红杰

前面不是写了么,1.0.2起才支持的,所以需要下载群里的体验版。
正式版,这周会尽快更新的。
1 赞 2018-10-29 11:33
余红杰

余红杰 回复 DCloud_客服_Trust

申请了,关键是提示这个错误“请求的页面无法打开:file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/hybrid/html/test.html at file:///android_asset/data/dcloud_error.html:41”
我就是新建了hybrid/html目标,然后把test.html放进去了,然后把模板的webview那个src改成/hybrid/html/test.html
0 赞 2018-10-29 11:32
DCloud_客服_Trust

DCloud_客服_Trust 回复 余红杰

4群:942702595
0 赞 2018-10-29 11:25
DCloud_客服_Trust

DCloud_客服_Trust 回复 余红杰

自 HBuilderX v1.0.2 起,在 5+App 平台下 web-view 支持加载应用内的 HTML 资源。
0 赞 2018-10-29 11:25
余红杰

余红杰 回复 DCloud_客服_Trust

群都是满的哦,而且
0 赞 2018-10-29 11:22
余红杰

余红杰

这个错误,我的hbuilderX是1.0.1.20181012啊!!
0 赞 2018-10-29 11:22
余红杰

余红杰 回复 DCloud_客服_Trust

:file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/hybrid/html/test.html at file:///android_asset/data/dcloud_error.html:41
0 赞 2018-10-29 11:21
DCloud_客服_Trust

DCloud_客服_Trust 回复 余红杰

检查下页面的地址,地址不正确的话无法加载。
如果是本地 html,请确认 HBuilderX 版本号是否正确。可以去QQ群下载体验版,本周更新正式版。
0 赞 2018-10-29 11:21
余红杰

余红杰

请求的页面无法打开是什么原因呢??
0 赞 2018-10-29 11:15

要回复文章请先登录注册