开发者社区 问答 正文

iOS WebView 业务场景IP连接有哪几种方法(1)


概述


本文主要介绍,防 DNS 污染方案在 WebView 场景下所遇到的一些问题,及解决方案。

WKWebView 无法使用 NSURLProtocol 拦截请求


针对该问题方案如下:

  1. 换用 UIWebView
  2. 使用私有API进行注册拦截

换用 UIWebView 方案不做赘述,说明下使用私有API进行注册拦截的方法:
  1. //注册自己的protocol
  2.     [NSURLProtocol registerClass:[CustomProtocol class]];
  3.     //创建WKWebview
  4.     WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc] init];
  5.     WKWebView * wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) configuration:config];
  6.     [wkWebView loadRequest:webViewReq];
  7.     [self.view addSubview:wkWebView];
  8.     //注册scheme
  9.     Class cls = NSClassFromString(@"WKBrowsingContextController");
  10.     SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:");
  11.     if ([cls respondsToSelector:sel]) {
  12.         // 通过http和https的请求,同理可通过其他的Scheme 但是要满足ULR Loading System
  13.         [cls performSelector:sel withObject:@"http"];
  14.         [cls performSelector:sel withObject:@"https"];
  15.     }

使用私有 API 的另一风险是兼容性问题,比如上面的 browsingContextController 就只能在 iOS 8.4 以后才能用,反注册 scheme 的方法 unregisterSchemeForCustomProtocol: 也是在 iOS 8.4 以后才被添加进来的,要支持 iOS 8.0 ~ 8.3 机型的话,只能通过动态生成字符串的方式拿到 WKBrowsingContextController,而且还不能反注册,不过这些问题都不大。至于向后兼容,这个也不用太担心,因为 iOS 发布新版本之前都会有开发者预览版的,那个时候再测一下也不迟。对于本文的例子来说,如果将来哪个 iOS 版本移除了这个 API,那很可能是因为官方提供了完整的解决方案,到那时候自然也不需要本文介绍的方法了。
注意避免执行太晚,如果在 - (void)viewDidLoad 中注册,可能会因为注册太晚,引发问题。建议在 +load 方法中执行。
然后同样会遇到 《HTTPS SNI 业务场景“IP直连”方案说明》 里提到的各种 NSURLProtocol 相关的问题,可以参照里面的方法解决。

展开
收起
猫饭先生 2017-10-20 11:04:33 2242 分享 版权
阿里云 AI 助理回答

在处理WebView中DNS污染问题时,您遇到了一些挑战,尤其是当使用WKWebView并尝试通过NSURLProtocol拦截请求时。由于WKWebView并不直接支持NSURLProtocol的拦截方式,您探索了几个解决方案,包括回退到UIWebView和利用私有API来绕过这一限制。下面是对您采取措施的一些补充说明和建议:

使用私有API的考量

  • 风险与兼容性:虽然使用私有API如WKBrowsingContextController可以实现对WKWebView请求的拦截,但这种方法存在一定的风险。苹果不鼓励在App Store应用中使用私有API,因为这可能导致审核被拒或在未来的iOS版本中功能失效。确保了解这些潜在后果。
  • 动态注册与时机:您提到注册私有API应在合适的时机进行,以避免因注册太晚而引发的问题。确实,选择在页面加载前尽早执行注册操作是明智的,比如在视图控制器的loadView或适当的初始化方法里完成,确保WebView创建和加载请求之前一切就绪。
  • SNI问题与HTTPS:您提到了《HTTPS SNI 业务场景“IP直连”方案说明》中的问题,表明即使是成功拦截了请求,也可能遇到SSL握手阶段的Server Name Indication (SNI)问题。解决这类问题通常需要在自定义的NSURLProtocol子类中正确处理SSL连接,确保SNI信息能正确传递给服务器。

替代方案探讨

  • 公共库与框架:考虑使用成熟的第三方库,如某些网络层的Swizzling技术库,它们可能已经解决了与WKWebView交互和请求拦截相关的难题,同时尽量保持与苹果官方政策的一致性。
  • Service Worker:对于更现代的Web应用,如果控制着网页内容,可以探索使用Service Worker作为替代方案来拦截和修改网络请求。但这依赖于网页端的配合,并且在iOS上的支持情况需具体测试。
  • 重定向策略:在服务器端实施重定向策略也是一种间接方法,通过识别特定条件将请求导向正确的地址,但这要求对后端有一定的控制权。

结论

在处理WKWebView的DNS污染问题时,采用私有API确实是一种可行的技术手段,但务必谨慎行事,充分评估长期维护的风险。同时,持续关注苹果官方的更新,寻找更稳定、官方推荐的解决方案。在开发过程中,也应准备应对策略,以便在未来iOS版本变动时能够快速调整。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答