全部产品
存储与CDN 数据库 安全 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 阿里云办公 培训与认证 物联网
HTTPDNS

iOS WebView 业务场景“IP直连”方案说明

更新时间:2017-09-30 16:57:35

概述

本文主要介绍,防 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 相关的问题,可以参照里面的方法解决。

单独成篇:《WebView 中的 Cookie 处理业务场景“IP直连”方案说明》

302重定向问题

上面提到的 Cookie 方案无法解决302请求的 Cookie 问题,比如,第一个请求是 http://www.a.com ,我们通过在 request header 里带上 Cookie 解决该请求的 Cookie 问题,接着页面302跳转到 http://www.b.com ,这个时候 http://www.b.com 这个请求就可能因为没有携带 cookie 而无法访问。当然,由于每一次页面跳转前都会调用回调函数:

  1. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;

可以在该回调函数里拦截302请求,copy request,在 request header 中带上 cookie 并重新 loadRequest。不过这种方法依然解决不了页面 iframe 跨域请求的 Cookie 问题,毕竟 -[WKWebView loadRequest:] 只适合加载 mainFrame 请求。

参考链接

相关的库:

相关的文章:

可以参考的Demo:

本文导读目录