WKWebView 使用的坑

  WKWebView 简介:

  WKWebView 是苹果在 WWDC 2014 上推出的新一代 webView 组件,用以替代 UIKit 中笨重难用、内存泄漏的 UIWebView。WKWebView 拥有60fps滚动刷新率、和 safari 相同的 JavaScript 引擎等优势。

  之前在使用 WKWebView 进行网络请求时,遇到了 HTTPBody 为空的问题,原因如下:

  WKWebView 在独立于 app 进程之外的进程中执行网络请求,请求数据不经过主进程,因此,在 WKWebView 上直接使用 NSURLProtocol 无法拦截请求。

  由于 WKWebView 在独立进程里执行网络请求。一旦注册 http(s) scheme 后,网络请求将从 Network Process 发送到 App Process,这样 NSURLProtocol 才能拦截网络请求。在 webkit2 的设计里使用 MessageQueue 进行进程之间的通信,Network Process 会将请求 encode 成一个 Message,然后通过 IPC 发送给 App Process。出于性能的原因,encode 的时候 HTTPBody 和 HTTPBodyStream 这两个字段被丢弃掉了

  因此,如果通过 registerSchemeForCustomProtocol 注册了 http(s) scheme, 那么由 WKWebView 发起的所有 http(s)请求都会通过 IPC 传给主进程 NSURLProtocol 处理,导致 post 请求 body 被清空;

  解决方案有以下几种:

  方案一:使用NSURLSession发送一个请求,然后把请求下来的数据当作本地HTML加载

NSURLSession *session = [NSURLSession sharedSession];
        // 创建请求Task
        NSURLSessionDataTask *task = [session dataTaskWithRequest:requestShare completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            // 将请求到的网页数据用loadHTMLString 的方法加载
            NSString *htmlStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            [self.wkWebView loadHTMLString:htmlStr baseURL:nil];
        }];
        // 开启网络任务
        [task resume];

  方案二:

原文地址:https://www.cnblogs.com/ZachRobin/p/10632835.html