WKWebView自定义URL方案不适用于https? (混合内容被阻止)

时间:2018-04-13 22:49:57

标签: ios swift safari wkwebview app-transport-security

我有一个WKWebView来加载一个网站,该网站有一个用WKURLScheme实现的自定义网址方案(mycustomurl://),该网站将使用GET调用。 当网站位于http://时,所有内容都按预期工作,但当我切换到https://时出现以下错误

[blocked] The page at https:// (url snipped) was not allowed to display insecure content from mycustomurl://(url snipped). 

WKURLScheme回调从未被击中,所以我怀疑Safari或更高的力量阻止了它:/

我已经梳理了关于ATS的SO讨论,但都没有奏效。 我确实看到像this one这样的讨论提到这是因为 Safari会阻止混合内容,而当我在Safari上直接尝试它时,确实产生了相同的结果(被阻止)。

似乎没有解决方案吗?我们似乎无法关闭Safari的混合内容限制。 那么应该如何使用和实现自定义URL方案,因为https应该总是比http更好的选择?

我注意到大多数自定义网址方案教程都有http而不是https ...

2 个答案:

答案 0 :(得分:1)

不确定此答案是否仍然有用,但实际的解决方案是使用自定义WKUrlSchemeHandler从中加载初始https页面。

我最近遇到了类似的问题(试图从https-页面连接到设备上的WebSocket服务器),而我发现要在仍通过https保护应用程序安全的同时实现此目的的唯一方法是,不错的解决方法:

  • WKUrlSchemeHandler注册您的自定义mycustomurl://
  • 注册自定义WKUrlSchemeHandler,例如myapp-remote://
  • webView:startURLSchemeTask:内部:
    • urlSchemeTask.Request中获取请求网址
    • myapp-remote://替换为https://
    • 使用https-url创建一个NSURLDataRequest
    • 将响应和获取的数据返回到urlSchemeTask

通过此设置,您可以通过使用myapp-remote://作为初始加载的模式来获取https-page,同时保持TLS安全性和验证性,并且可以使用mycustomurl://引用{{1} }不会阻止。

我的实现是在Xamarin的C#中实现的,但是如果需要的话,我可以提供它来简化说明。

答案 1 :(得分:0)

根据Apple Office演示:https://developer.apple.com/videos/play/wwdc2017/220/

1,添加代码

+(NSDictionary *)cacheDicSchema {
    return @{@"mwweb-local":@"http",
             @"mwweb-locals":@"https"};
}

-(void)hk_setPreferences:(WKPreferences *)perferences {
    [self hk_setPreferences:perferences];

    if (@available(iOS 11.0, *)) {
        for (NSString *key in [[[self class] cacheDicSchema] allKeys]) {
            [self setURLSchemeHandler:[[WeakSchemeHandler alloc] init]  forURLScheme:key];
        }
    }
}

2,将contentRuleList作为值,并编译成wkwebview

[
 {
 "trigger":
    { "url-filter" : ".*"
    },
 "action": {
    "type" : "make-https"
    }
 }
 }
]

编译到WKWebView

   if (@available(iOS 11.0, *)) {
        [[WKContentRuleListStore defaultStore]
         compileContentRuleListForIdentifier:@"MWWKWebViewContentRules" encodedContentRuleList:contentRuleList
         completionHandler:^(WKContentRuleList *contentRuleList, NSError *error) {
             if (error == nil) {
                 [config.userContentController addContentRuleList:contentRuleList];
             }else{
                MWHYLog(@"compileContentRuleListForIdentifier Error == %@",[error description]);
             }
         }];

}

3,用html

 <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta nemo name="basepath" content="/c_mboss/smartcloud">

    <script nonce="abc">
        var domDoc = document.documentElement;
        var domMeta = document.querySelector('meta[name="viewport"]');
        var dpr = window.devicePixelRatio || 1;
        //        var dpr = 1;
        var scale = 1 / dpr;
        var rem = domDoc.clientWidth * dpr / 7.5;
        var content = 'width=' + domDoc.clientWidth * dpr +
            ', initial-scale=' + scale +
            ', maximum-scale=' + scale +
            ', minimum-scale=' + scale +
            ', user-scalable=no';

        domMeta.setAttribute('content', content);
        domDoc.style.fontSize = rem + 'px';
      </script>
    <title>XXX</title>
    <link href="https://webresource.mwee.cn/c_mboss/smartcloud/v_20180515163218/css/dist/main.min.css" rel="stylesheet">
</head>

<body>
    <div id="appview"></div>
    <input id="umengId" value="1264335506" style="display:none;" />

    <img> src="mwweb-locals://XXXXX/index/kdxz.png"/>

    <script type="text/javascript" src="mwweb-locals://XXXXX/js/mmm.js"></script>
    <script type="text/javascript" src="mwweb-locals://XXXXX/js/app.js"></script>
</body>
</html>

<img>确实如苹果所说。

<script>从不工作,我一次又一次尝试............

Safari出现错误

[Warning] The page at https://10.88.3.95:3334/c_mboss/smartcloud/index/index was allowed to display insecure content from mwweb-locals://XXXXX/index/kdxz.png. (index, line 44)

[Warning] [blocked] The page at https://10.88.3.95:3334/c_mboss/smartcloud/index/index was not allowed to run insecure content from mwweb-locals://XXXXX/js/mmm.js.

[Warning] [blocked] The page at https://10.88.3.95:3334/c_mboss/smartcloud/index/index was not allowed to run insecure content from mwweb-locals://XXXXX/js/app.js.

我猜内容安全策略确实与WKWebView中的WKSchemeHandler冲突,内容安全策略将阻止在WKSchemeHandler之前加载静态资源的过程。

奇怪的是,一旦将contentRuleList添加到loadRequest网站https://XXXXX的WKWebView中,它为何阻止<img>而不阻止<script>