mPaas-WKWebview网络拦截常见问题

简介:mPaas-WKWebview网络拦截常见问题

image.png

1. 背景

原生WKWebView在独立于app进程之外的进程中执行网络请求,请求数据不经过主进程,因此在 WKWebView 上直接使用NSURLProtocol 是无法拦截请求的。但是由于mPaas的离线包机制强依赖网络拦截,所以基于此,mPaas利用了WKWebview的隐藏api,去注册拦截网络请求去满足离线包的业务场景需求,参考代码如下:

[WKBrowsingContextController registerSchemeForCustomProtocol:@"https"]

但是因为出于性能的原因,WK的网络请求在给主进程传递数据的时候会把请求的body去掉,导致拦截后请求的body参数丢失。在离线包场景,由于页面的资源不需要body数据,所以离线包可以正常使用不受影响。但是在H5页面内的其他post请求会丢失data参数。为了解决post参数丢失的问题,mPaas通过在js注入代码,hook了js上下文里的XMLHTTPRequest对象解决。通过在JS层把方法内容组装好,然后通过WKWebView的messageHandler机制把内容传到主进程,把对应HTTPBody然后存起来,随后通知JS端继续这个请求,网络请求到主进程后,在将post请求对应的HttpBody添加上,这样就完成了一次post请求的处理。整体流程可以参考之前崔同学的分享流程图如下:

1620448978855-64d98dd0-84d6-4cde-acf4-cae9b62f0779.png
图1

2. 遇到的问题

通过上面的机制,既满足了离线包的资源拦截诉求,也解决了post请求body丢失的问题。但是在一些场景还是存在一些问题,需要开发者进行适配。

2.1. mPaas容器和三方容器混用导致三方容器请求body丢失
2.1.1. 问题场景

典型的场景,是在App内同时集成了多个wkwebview容器,常见的问题现象如下:打开mPaas容器后在打开三方的WK页面,三方WK页面内的post请求body参数丢失。原因是因为mPaas容器注册了全局的网络拦截,导致三方容器内的请求,也走到了mPaas的网络拦截,但是因为mPaas容器没有启动,所以无法正常走到mPaas全局拦截补全body的链路,导致body参数丢失。

2.1.2. 解决方案

在三方容器创建的时候反注册,在销毁的时候再注册回来。

j//反注册
Class cls = NSClassFromString(@"WKBrowsingContextController");
    SEL sel = NSSelectorFromString([NSString stringWithFormat:@"unregisterSchemeForCustomProtocol:"]);
    if ([(id)cls respondsToSelector:sel]) {
        [(id)cls performSelector:sel withObject:@"http"];
        [(id)cls performSelector:sel withObject:@"https"];
    }
  
  //注册
    Class cls = NSClassFromString(@"WKBrowsingContextController");
    SEL sel = NSSelectorFromString([NSString stringWithFormat:@"registerSchemeForCustomProtocol:"]);
    if ([(id)cls respondsToSelector:sel]) {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [(id)cls performSelector:sel withObject:@"http"];
        [(id)cls performSelector:sel withObject:@"https"];
    #pragma
    }
2.2. mPaas容器打开离线包后直接访问虚拟域名导致白屏
2.2.1. 问题场景

和上面第一个case类似,也是在App内同时集成了多个wkwebview容器,同时三方的容器也会操作全局的网络拦截,导致mPaas的网络拦截失效。常见的问题现象如下:打开三方容器后,在打开mPaas的离线包后,发现离线包会直接通过在线网络访问虚拟域名,不走离线,导致页面白屏。

2.2.1. 解决方案

参考第一个问题的解决方案,在启动mPaas容器的时候,确认全局的网络拦截是可以正常生效的就可以。

2.3. mPaas容器内sendBeacn请求body丢失
2.3.1. 问题场景

有客户在容器内集成了神策的埋点jssdk,发现埋点请求里的body参数丢失。通过查看源码发现神策jssdk是通过navigator.sendBeacon发送的请求,目前mPaas内hook的js请求,只支持XMLHTTPRequest,sendBeacon还不支持,所以导致走了网络拦截后body参数丢失。

1620455454211-830ae69c-bf20-41ee-8ede-7e7ce80303b7.png
图2

2.3.1. 解决方案

神策sdk内支持指定ajax的方式上报埋点,修改上报方式为ajax后问题解决。可参考文后资料[1]了解详情。

1620455672344-6ded744e-6937-4b73-99ff-3494b6ccadb6.png
图3

[1]JavaScript SDK 使用说明:https://www.sensorsdata.cn/2.0/manual/js_sdk.html

我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。我们期望能够分享更多帮助企业客户上云、用好云,让客户云上业务运行更加稳定可靠的技术,您可用钉钉扫描下方二维码,加入阿里云SRE技术学院钉钉圈子,和更多云上人交流关于云平台的那些事。

原文链接:https://developer.aliyun.com/article/784303?

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值