Code前端首页关于Code前端联系我们

携程小程序Webview实用指南:内嵌H5的问题与解决方案

terry 2年前 (2023-09-22) 阅读数 87 #移动小程序
携程小程序webview实践指南:内嵌H5的问题及解决方案

1.背景

本文将与大家分享团队以微信小程序为主要环境进行小程序Webview的开发经验,并介绍公司。内嵌H5遭遇的问题和解决方案在开发过程中得到解决。 根据小程序平台与H5的区别、小程序内嵌的webview通信以及小程序webview的常见问题进行详细描述。

2。平台差异

下面简单分析和讨论小程序与H5的几个显示差异。 携程小程序webview实践指南:内嵌H5的问题及解决方案

2.1 小程序

以微信小程序为例,相信今天大多数读者都熟悉微信小程序的系统架构。总的来说分为两部分:

  • view View端通过小程序框架将用户使用WXML、WXSS描述的UI信息处理成H5元素,最终传输到WebView进行显示;逻辑层
  • 执行JS逻辑,可以调用JSAPI,对微信有开放能力。逻辑和表示是分离的,并通过事件和数据连接起来。
携程小程序webview实践指南:内嵌H5的问题及解决方案

微信小程序使用WebView渲染,它与原生客户端有两种不同的渲染系统。一个小程序有多个界面,因此渲染层有多个WebView。逻辑层使用JSCore线程来执行JavaScript脚本。两个线程之间的通信是通过小程序的native端传递的,逻辑层发送的网络请求也是通过native端传递的。

这个设计的初衷是为了控制和安全。微信小程序阻止开发者使用某些浏览器的开放接口,例如页面跳转、操作DOM、动态执行脚本等。将逻辑层和显示层分离,使得显示层和逻辑层之间只能进行数据通信,可以防止开发者随意操作界面,可以更好地保证用户数据的安全。同时,小程序设计了组件框架——Exparser。基于该框架,内置了一系列组件,涵盖了小程序的基本功能,可以让开发者快速构建任意界面。它还提供了为开发人员定制组件的能力。您可以自己扩展更多的组件来实现代码复用。

值得一提的是,一些更复杂的内置组件是由客户端原生渲染的。同时,微信团队结合Flutter和LV-CPP,融合C++和Dart上的实现代码,基于小程序技术栈进一步简化实现,实现跨平台业务开发的框架维护成本,获得更好的性能。

2.2 小程序WebView 内嵌H5

H5页面放置在小程序WebView中。配置合法域名后即可在小程序中显示。对于不同制造商的小程序,法律问题和制造商合规性可能会有所不同。 H5需要定义环境,调用不同的API方法,展示不同的业务页面。

CWX小程序SDK封装在携程中。小程序主要采用原生+Taro框架。 H5部分主要使用NFES(React)和Vue。无论是哪一端通过CWX连接,内部封装都提供所有终端通用的功能,如登录、发布、支付、个人中心等功能。这些函数可以通过CWX中间件直接调用。

另外,当H5检测到当前处于小程序webview环境时,会根据环境异步加载SDK文件和厂商JS SDK,并初始化小程序版本 wx.config 。这里的关键点是我们需要创建一个 API 调用队列。由于SDK是异步加载的,如果在此期间对页面进行API调用,肯定得不到正确的答案。因此,我们需要在SDK初始化后创建一个调用队列并处理这些调用。其实CWX的原理非常纯粹。如果要实现多终端定制,只需要根据环境加载不同的SDK即可。

>这里简单列出了一些小程序在工作中常见的环境评估: 携程小程序webview实践指南:内嵌H5的问题及解决方案

使用注意事项:

在使用之前,最好查看相应小程序的文档,因为每个小程序对API有一定的要求。支持级别各不相同。引用bridge.js的方式根据情况而定,因为bridge.js引入JSSDK的方式是在head标签中添加一个script标签。如果head标签中引入bridge.js,则会报错。当您打开 h5 时,它会显示“页面访问受到限制”。 '等提示信息,您可以尝试以下操作:(这种情况一般出现在打开测试环境的h5 url时)在IDE中勾选“忽略webview域名合法性检查”和“忽略域名合法性检查请求”

【快应用相关】

目前,Vivo、Oppo、华为三个厂商已支持新版本快应用,其中Vivo、OPPO已上线,华为正在测试,小米暂不支持。对于新版本快应用H5页面需要调用新版本快应用JS SDK提供的API,H5链接的域名必须预先配置为可信URL(配置必须为以正则表达式的形式编写)。

【今日头条相关】

今日头条小程序的redirectTo、NavigateTo等页面跳转接口仅支持URL以/开头的绝对路径。

【支付宝相关】

bridge.js当前版本1.0.73判断是否在支付宝小程序中。会判断h5是在支付宝小程序中,和支付宝小程序中一样,h5是在内置支付宝浏览器中。 。因此,在自定义my.XXXX之前,应该调整环境工具功能,确保其确实在支付宝小程序中,而不是在支付宝内置浏览器中。 ?经调查,该方法在iOS上可以正常激活,但在Android手机上却无法正常激活。

所以我们有以下解决方案。该方案需要同时处理h5和小程序的webview。关键思想:使用webview的哈希函数。

  • 小程序通过hash传递参数,页面不更新(这个和浏览器是一样的)
  • h5可以通过hashchange捕获最新的参数,进行自定义逻辑处理
  • 最后运行window.history.go (-1 )

为什么我们需要运行 window.history.go(-1)?因为hash变化导致web视图历史的堆栈长度变成+1,用户不得不再次返回。但这一步显然是不必要的。同时,window.history.go(-1)之后,hash中webview添加的参数会被去掉,也可以保证和之前的URL一致。

3.2 评论

为了顺利接入,我们不能采取一刀切的做法。我们必须确保现有页面无需任何更改即可访问。新功能必须通过附加参数来区分,例如:检测URL中的查询部分,使用__isonshowpro=1,然后通过散列传递参数。改变原来的逻辑,使得当__isonshowpro=1时,哈希处理逻辑具有最高的参数定义,并在前面添加两个下划线以区分URL中的正常参数。我们看看h5端sdk是如何实现的。携程小程序webview实践指南:内嵌H5的问题及解决方案

总结起来有两点:

  • onShow方法的实现

绑定一个hashchange事件(这里进行处理是为了避免重复绑定事件),并将传入的自定义onShow事件缓存在一个数组中时hashchange被触发,根据唯一标志位__isonshow和__wachangehash判断是否被触发。

  • serviceDone方法的实现

触发条件:立即声明最后一个onShow触发,也可以通过
wx.miniProgram.postMessage指定发送数据的URL。

浏览器可以通过URL地址访问资源。如果内嵌的H5的地址没有变化,则Web视图访问资源都是从缓存中取,缓存中没有最新的数据,导致服务器端的数据是最新的。资源根本无法到达浏览器,这也解释了为什么更改Nginx的Cache-Control配置可能没有效果。

所以想要彻底解决及时刷新的问题,需要允许web视图访问新地址。我们假设小程序访问的URL地址为:
https://www.yourdomain.com/101/#/index ,其中101是构建的版本号,每次都会递增,以保证这个每次都是如此不同。

4。 Webview常见问题及解决方案

小程序和h5之间的通信基本上有两种常见的方法。其中之一是 postMessage。众所周知,这个方法只能在三种情况下被激活:返回、销毁和共享。但也有一个问题:需要注意的是,该方法仅受基础库1.7.1支持。 1.7.1之后,只能通过第二种方式传递数据,即设置并检测webview组件的URL变化,类似于PC当时的iframe通信方式。

在SDK中如何做到这一点?定义共享方法首先要检查基础库版本是否支持postMessage。如果支持直接调用,如果不支持,则链接URL中的共享参数,然后重新加载。 。换句话说,通过 URL 传递数据有一个缺点,即页面可能需要刷新一次才能设置成功。

目前 webview 环境支持了几个常用的服务:

4.1 返回左上角

当你打开小程序的 webview 页面时,首先进入的是一个空白的转账页面,然后输入h5页面,以便后退按钮出现在左上角。当用户按下左上角的返回按钮时,页面将重新加载到小程序的首页。这个看似简单的小动作,实际上对公司影响很大。

经过我们的统计,我们发现左上角返回按钮的点击率高达70%以上,因为这类着陆页一般都是用户共享的。以前纯h5的时候,只能通过左上角返回,所以在小程序中用户也习惯了;第二期,重新加载首页后下一页访问率超过10%。这两个数字对于业务提升来说其实是相当大的。实现原理很简单:第二次激活onShow时处理。 ?通过您自己的 url 上的参数进行管理。 携程小程序webview实践指南:内嵌H5的问题及解决方案

从一开始就需要登录状态。具体来说,在加载webview之前,首先授权登录,然后在URL中链接登录信息,然后加载webview并在h5中使用适配器传递登录信息。提取出来保存到cookie中,这样h5进来的时候就登录了。

如果一开始不需要登录,一进入小程序就可以直接通过webview加载h5。当h5调用login方法时,将needLogin参数附加到url上,然后使用API​​重新加载它,然后就完成了。在一种情况下,执行授权登录。 ?嵌套的 webview 主页不会触发react-imvc onshow 事件。这个页面比较旧,注销也一样,所以跳过了首页的h5登录,而不是小程序登录,导致登录不同步。

解决办法:需要返回首页刷新h5页面。

误区:个人登录后立即重启到首页会导致注销Web视图没有立即调用替换token而无法退出。

解决方案:要控制何时从个人页面返回,设置webview URL添加参数并刷新即可。

4.3 Webviwe分享携程小程序webview实践指南:内嵌H5的问题及解决方案

在连接websocket之前,小程序主要使用bind。首先通过bindmessage事件接收h5返回的数据,然后用户分享时,onShareAppMessage判断是否有返回数据。如果没有,它会去 webviewurl 检索它。否则,使用默认共享信息。

4.4 支付

1)刷新网页视图页面时出现问题

因为小程序网页视图不支持微信直接支付,所以如果需要支付,基本都要到小程序去然后付款后回去。 。完成以上之后,简单提一下h5中的一句话。

对于内嵌H5页面较多的产品,最好分成两个支付页面,具体取决于公司。首先,有些公司h5有自己完整的交易系统,下单动作可以在h5中完成。他们只需要小程序支付,所以我们有一个精简的支付页面,你一走进去就可以开始微信支付。

还有一种情况是,公司需要小程序提供完整的订单支付流程,直接进入小程序结账。上图展示了SDK中的基本逻辑。 payOnly 参数用于确定打开哪个页面。我们来看看小程序是如何实现简化支付的。加载完成后,立即调用API发起微信支付。支付成功后,根据h5返回的参数,如果是小程序页面,则直接进入,否则刷新之前的网页视图页面。 ,然后返回。

新问题与挑战:webview返回上一页、数据刷新问题

有客户反映,点击A页面任务后,跳转到B页面。任务完成后,手机退出手势滑动返回或点击默认导航栏。返回页面左上角且上一页不会触发任务更新。原因是之前的页面已经初始化了,还没有进行重新渲染。在APP环境下,JSBridge不提供监听向左返回手势或者左上角物理返回的回调事件。小程序的webview页面也会出现上面提到的同样的情况。

由于微信不提供左滑返回或左上角物理返回的监听手势,且网页视图页面不支持自定义导航栏,所以导致下一页触发的新事件无法实现返回上一页时执行。进行有针对性的更新。初期可以简单粗暴的使用约定的参数doRefreshWhileBack=true作为选项,在Web视图页面每次刷新页面,但刷新整个页面的成本太高,用户体验不好。

2)websocket介绍

带着这些问题,我们进行了一系列的尝试和实验,最终采用了websocket的方式来解决和封装我们市场业务的轻量级websocket服务,主要用于解决webview业务的跨页面通信和游戏方面的问题。

在这个过程中,我们总结了一些经验,希望能为从事相关研究的同学提供一些帮助。上述做法是针对不同的应用环境,使用或约定不同的API分发到各自的事件系统,从而解决了页面物理回滚时页面不主动刷新的问题。

简单介绍一下websocket。 websocket标准诞生于2011年,其RFC文档号为6455。TML 5规范定义了WebSocket协议,可以通过HTTP端口(或HTTPS端口)完成,保持对HTTP协议透明防火墙的友好。最大尺寸。但它是真正的双向全双工协议,即客户端和服务器端都可以主动发起请求并响应响应,双方的传输是相互独立的。与上面的Comet不同,WebSocket的服务端推送是可以由服务端独立主动发起的,因此是服务端的“真正的推送”。

WebSocket 是一种二进制协议,可以说是有“专业背景”,不会有这么大的 header 开销。这样解决了运营商需要反复解析HTTP协议并检查身份信息的问题,从而传输效率更高。 。同时,与HTTP不同的是,它是一个有状态的协议。双方可以就某种状态达成一致,而无需在转让过程中进行考虑。而且,与HTTP相比,WebSocket没有同源限制。服务器地址可以完全独立于源页面地址,即不会出现浏览器的“跨域问题”。 携程小程序webview实践指南:内嵌H5的问题及解决方案

好处:

  • 实时消息传递:真正的双向、全双工协议,全服务器推送保证数据时效性。
  • 高效通信:客户端和服务器可以主动发送请求,不会产生轮询等大量无效传输消息。
  • 协议支持:标准诞生较早,浏览器支持度高,无同源策略限制。

缺点:

  • 开发维护成本:长期维护服务器上的长连接会产生一定的成本,并且受网络限制,必须处理重连。

有了websocket的帮助,小程序webview内嵌H5的业务场景可以做更多的事情。在市场的网页上您可以查看集装箱的装载过程。? 初始化webview套接字服务并接受服务器消息-筛选服务器消息。如果H5页面通过socket传递给webview容器的数据格式符合预期,并且H5环境中登录状态的openId与小程序环境一致,那么就认为这次通信是合法的;

webview容器链接了miniShare、openScribe、健康检查等常见业务API,用于处理广告、订阅、任务更新等的实时回调;这使得 H5 事务变得易于访问。接口设置激活小程序原页面的部分原生功能,为母公司提供服务。

H5页面可以通过socket通信更改和调用小程序的胶囊栏,通知webview容器页面调用小程序广告,还可以调用小程序页面的分享面板,并在有异常情况时触发及时通知左上角的物理返回已激活。 H5页面激活回调等多种服务;同时,小程序容器页面的原生事件完成后(如广告、分享),将H5页面的回调通过socket发送回H5页面,实现小程序容器页面之间的实时通信。小程序网页视图。

在websocket的支持下,webview小程序目前拥有更多与H5通信的功能。 ? 。 携程小程序webview实践指南:内嵌H5的问题及解决方案携程小程序webview实践指南:内嵌H5的问题及解决方案

4.6 H5调用小程序原生激励广告

H5页面可以通过WebSocket通信调用小程序原生激励广告。?它们位于不同的容器下,因此无法进行通信和通知;但只要两个页面加载同一个市场的websocket服务,就可以设置服务器共享一个redis,通过redis的发布订阅功能连接集群中的不同机器,然后进行相应的回调事件。页面前进或后退时绑定,可以灵活更新任务组件,向用户展示最新的任务状态。

5.总结

对于小程序webview的处理,可以封装一个包含各端环境的SDK,并在H5初始化时加载,打通H5与小程序webview之间的通道,实现H5的共享- 控制、登录状态同步、支付信息同步等功能。

在遇到跨多个页面刷新数据的问题时,我使用websocket的工具,通过redix的发布订阅通知从websocket服务器链接页面,从而实现小程序webview物理返回上一页的问题无需数据刷新。同时Websocket使得H5与webview的通信更加方便灵活,扩展了H5的功能:调用小程序自带的激励广告、封装调用小程序自带的子面板等功能。 ? Olivio,携程高级前端开发工程师,专注于React Node组件化;

Stone,携程高级研发经理,专注于跨端解决方案、云原生落地等领域。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门