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

bka*_*ooo 5 safari ios swift wkwebview app-transport-security

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

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

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

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

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

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

Shi*_*rin 7

不确定这个答案是否仍然相关,但实际的工作解决方案是使用自定义WKUrlSchemeHandler来加载初始 https 页面。

我最近遇到了类似的问题(尝试从 https 页面连接到设备上的 WebSocket 服务器),我发现在保持应用程序受 https 保护的同时使其正常工作的唯一方法是以下不太好的解决方法:

  • 注册您的WKUrlSchemeHandler定制mycustomurl://
  • 注册第二个自定义WKUrlSchemeHandler,比方说myapp-remote://
  • 里面webView:startURLSchemeTask:
    • 从 中检索请求 urlurlSchemeTask.Request
    • myapp-remote://用。。。来代替https://
    • NSURLDataRequest使用 https-url创建一个
    • 返回响应并获取数据到urlSchemeTask

通过此设置,您可以使用初始加载的架构来获取 https 页面myapp-remote://,保持 TLS 安全性和验证,并且还具有您不会阻止mycustomurl://的工作引用。WKWebView

我的实现是使用 Xamarin 的 C# 实现的,但如果需要,我可以提供它以便清楚起见。


aiq*_*ong 0

据apple office Demo: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];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2、将contentRuleList作为值,并编译到wkwebview中

[
 {
 "trigger":
    { "url-filter" : ".*"
    },
 "action": {
    "type" : "make-https"
    }
 }
 }
]
Run Code Online (Sandbox Code Playgroud)

编译成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]);
             }
         }];

}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

<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.
Run Code Online (Sandbox Code Playgroud)

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

这里很奇怪,为什么它会被阻止<img>,但<script>一旦您将 contentRuleList 添加到 WKWebView 的 loadRequest 网站https://XXXXX中,它就不会被阻止。