相关文章推荐
酒量大的充电器  ·  如何将 LINQ ...·  9 月前    · 
眉毛粗的油条  ·  expect.assertions(1) ...·  1 年前    · 
跑龙套的小蝌蚪  ·  java - gson throws ...·  1 年前    · 

WKWebView的网络请求一直是一个头疼的问题。坊间流传三大方案皆存在致命瑕疵:

  • 方案一:走私有api注册NSURLProtocol, 但XHR 请求丢失 body 的问题,所以要js注入封装一层 myXHR 代替 XHR。然而如果在工程中使用了iframe, 回调就乱了。遂放弃。
  • 方案二: WKURLSchemeHandler自定义,要h5处理。弃。
  • 方案三: 所有的网络请求走native,通过messagehandler转发。h5改动更大, 弃。
  • 去年拜读了很多文章等文章。但是确实以为这条路是堵死了。也看了大神们如何解决丢body问题。 WKURLSchemeHandler 的能与不能 这篇也很详尽。

    看一看WebKit2源码也会觉得绝望。毕竟网络请求都不在一个进程里。想要拦截真的很难。

    惊天大反转

    但是有时候解决问题的方式确实没那么复杂。也许关键还是在多看一点源码。解决问题的关键在 WKWebViewConfiguration.mm 这个实现里

    - (void)setURLSchemeHandler:(id <WKURLSchemeHandler>)urlSchemeHandler forURLScheme:(NSString *)urlScheme
        auto *urlSchemeHandlers = _urlSchemeHandlers.get([] { return adoptNS([[NSMutableDictionary alloc] init]); });
        if ([WKWebView handlesURLScheme:urlScheme])
            [NSException raise:NSInvalidArgumentException format:@"'%@' is a URL scheme that WKWebView handles natively", urlScheme];
    复制代码

    这里就是 WKURLSchemeHandler 的能与不能 这篇文章里写的,为何大部分已知的约定俗称的都不能定义,包括,https、http、about,当然也包括,data、blob、ftp 等,如果你这样做了,会收到一个crash。

    所以思路是不是很简单?只要 [WKWebView handlesURLScheme:urlScheme] 一直返回NO不就行了?

    所以是不是只要

    @implementation WKWebView(handlesURLScheme)
    + (BOOL)handlesURLScheme:(NSString *)urlScheme
        return NO;
    复制代码

    这么几行代码就行了?

    有兴趣去看看我的库 SSWKURL ,给了更具体的实现。

    另外这个我不是第一个发现的,应该有很多同学已经比我更早发现了...

    分类:
    iOS
  •