前言
随着微信小程序的广泛应用,小程序的用户越来越多,但受其小程序体积限制的影响,不能够完全满足用户的要求,应运而生的web-view组件很好的解决的这一问题。
web-view主要是内嵌H5网站页面又以下几个优点:
- 内嵌web-view能够直接运行在小程序中,大大减少了用户的开发成本
- 能够实现小程序与h5的跳转,有良好的扩展性,方便用户多端间引流
小程序相关API
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
src | string | 否 | webview 指向网页的链接。可打开关联的公众号的文章,其它网页需登录小程序管理后台配置业务域名。 | 1.6.4 | |
bindmessage | eventhandler | 否 | 网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息。e.detail = { data },data是多次 postMessage 的参数组成的数组 | 1.6.4 | |
bindload | eventhandler | 否 | 网页加载成功时候触发此事件。e.detail = { src } | 1.6.4 | |
binderror | eventhandler | 否 | 网页加载失败的时候触发此事件。e.detail = { url, fullUrl },其中 fullUrl 为加载失败时的完整 url | 1.6.4 |
一、webview内嵌网页的授权认证
1.内嵌页面
// miniprogram/pages/2.18/web-view/index.js
Page({
/**
* 页面的初始数据
*/
data: {
url:'',
webViewData:{}
},
onReceivedMessage(e){
let data = e.detail.data
// data可能是多次 postMessage 的参数组成的数组
if (Array.isArray(data)) data = data[0]
console.log('onReceivedMessage',JSON.parse(data));
this.setData({
webViewData:JSON.parse(data)
})
},
onShareAppMessage(options) {
console.log('title',this.data.webViewData.title);
console.log('webViewUrl',options.webViewUrl)
return {
title: this.data.webViewData.title,
path: `/web-view/index?web-view-url=${options.webViewUrl}`
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let token = getApp().globalData.token
let url = `http://localhost:3000/user/web-view?token=${token}`
console.log('token', token);
this.setData({
url
})
},
})
<web-view bindmessage="onReceivedMessage" src="{{url}}" style="z-index:-1"></web-view>
2.登录页面
Page({
/**
* 页面的初始数据
*/
data: {},
onShareAppMessage:function(options) {
console.log('分享')
return {
title: '登陆',
path: '/pages/index'
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// wx.showShareMenu({
// withShareTicket: true
// })
},
})
<view class="page-section">
<text class="page-section__title">微信登陆</text>
<view class="btn-area">
<button bindgetuserinfo="login" open-type="getUserInfo" type="primary">登陆</button>
<navigator style="padding-top:20rpx;" url="/web-view/index" open-type="navigate">web view</navigator>
<button open-type="share" type="primary">分享</button>
</view>
</view>
二、web端相关函数
1.判断是否是小程序环境
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<script type="text/javascript" src="/static/js/jweixin-1.6.0.js"></script>
<script type="text/javascript" src="/static/js/jquery.js"></script>
<script type="text/javascript" src="/static/js/jquery.cookie.js"></script>
<style>
* {
font-size: 24px;
}
</style>
</head>
<body>
{{title}}
{{if title}}
<p>has title.</p>
{{/if}}
<p>
{{each title $value $index}}
<span>{{$index}}:{{$value}}</span>
{{/each}}
</p>
<p>
{{each arr }}
<span>{{$index}}:{{$value}}</span>
{{/each}}
</p>
<p>{{now | dateFormat "yyyy-MM-dd hh:mm:ss"}}</p>
<p>Art-Template Welcome to {{title}}</p>
<input value="ly" /><br /><br />
<input type="button" value="send"></input>
<p ></p>
<input type="button" value="share" style="width: 100px;height:30px;border:solid 1px grey;"></input>
<script type="text/javascript">
// 当处于小程序内
document.addEventListener('intoMiniprogram', () => {
retrieveHomeData()
}, false)
// 检查是不是位于小程序内
let isInMiniprogram = false
function changeIsInMiniprogramState() {
if (!isInMiniprogram) {
isInMiniprogram = true
$.cookie("isInMiniprogram", true)
document.dispatchEvent(new Event('intoMiniprogram'))
console.log('isInMiniprogram', isInMiniprogram);
}
}
if (/token=\d+/.test(window.location.search)) {
changeIsInMiniprogramState()
} else if ( /miniProgram/.test(navigator.userAgent) ){
changeIsInMiniprogramState()
}else if (($.cookie("isInMiniprogram") || '') == 'true') {
changeIsInMiniprogramState()
} else {
function onWeixinJSBridgeReady() {
if (window.__wxjs_environment === 'miniprogram'){
changeIsInMiniprogramState()
}
}
if (!window.WeixinJSBridge || !WeixinJSBridge.invoke) {
document.addEventListener('WeixinJSBridgeReady', onWeixinJSBridgeReady, false)
} else {
onWeixinJSBridgeReady()
}
}
// retrieveHomeData()
// 在小程序中,模拟调用接口
function retrieveHomeData() {
$('#send-btn').bind('click', (e) => {
let name = $('#name').val()
console.log('name', name);
let authorization = $.cookie("Authorization") || ''
$.ajax({
url: `http://localhost:3000/user/home?name=${name}`,
method: 'get',
headers: {
'Authorization': authorization
},
success(res) {
console.log('res', res)
$("#output").text(JSON.stringify(res))
},
fail(err) {
$("#output").text(err)
}
})
})
$('#share-btn').bind('click', (e) => {
console.log('share btn click')
wx.miniProgram.postMessage({
data: JSON.stringify({
action: 'share',
title: window.document.title
})
});
// wx.miniProgram.navigateBack()
})
}
</script>
<script type="text/javascript" src="/static/js/vconsole.min.js"></script>
<script>
// 初始化
var vConsole = new VConsole();
console.log('Hello world');
</script>
</body>
</html>
接口端
// 一个web-view页面,是给小程序加载的
router.all('/web-view', async function (ctx) {
let token = ctx.request.query.token
ctx.session.sessionKeyRecordId = ~~ctx.session.sessionKeyRecordId + 1
if (token) ctx.cookies.set('Authorization', `Bearer ${token}`, { httpOnly: false });
let title = 'web view from koa' + ctx.session.sessionKeyRecordId
await ctx.render('index', {
title,
arr: [1, 2, 3],
now: new Date()
})
});