ios WKWebView 不加载 https URL?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32437577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:32:52  来源:igfitidea点击:

WKWebView does not load https URL?

iosobjective-ciphoneswiftwkwebview

提问by confile

I have a WKWebView which should load the following url:

我有一个 WKWebView 应该加载以下网址:

https://buchung.salonmeister.de/place/#offer-details-page?id=907599&venueId=301655

Her is the code I use:

她是我使用的代码:

import UIKit
import WebKit


class MMWKBrowserController: UIViewController {

  private let closeButtonSelector: Selector = "closeButtonTapped:"

  private var urlString: String
  private let request: NSMutableURLRequest

  private var webView: WKWebView!
  private var twoLineTitleView: UIView!
  private var titleLabel: UILabel?
  private var subTitleLabel: UILabel?
  private var indicator: UIActivityIndicatorView!


  init(urlString: String) {
    self.urlString = urlString

    println("*** Using MMWKBrowserController ***")

    var url: NSURL? = NSURL(string: urlString)
    if url == nil {
      var escapedString: String = urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
      self.urlString = escapedString
      url = NSURL(string: escapedString)
    }

    println("url: \(url)")
    request = NSMutableURLRequest(URL: url!)

    request.setValue("Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H141 Safari/600.1.4", forHTTPHeaderField: "UserAgent")

    super.init(nibName: nil, bundle: nil)
  }

  required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }


  deinit {
    self.webView.removeObserver(self, forKeyPath: "loading")
    self.webView.removeObserver(self, forKeyPath: "title")
    self.webView.removeObserver(self, forKeyPath: "URL")
    self.webView.removeObserver(self, forKeyPath: "estimatedProgress")
    self.webView.stopLoading()
  }


  override func viewDidLoad() {
    super.viewDidLoad()
    createNavigationView()


    self.navigationController?.navigationBar.tintColor = MGColor.actionColor

    let config = WKWebViewConfiguration()
    self.webView = WKWebView(frame: self.view.bounds, configuration: config)
    self.view.addSubview(self.webView)


    indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
    //indicator.backgroundColor = UIColor(white: 0.1, alpha: 0.5)
    webView.addSubview(indicator)

    self.webView.snp_makeConstraints { (make) -> Void in
      make.edges.equalTo(self.view)
    }

    indicator.snp_makeConstraints { (make) -> Void in
      make.center.equalTo(self.webView)
    }

    webView.addObserver(self, forKeyPath: "loading", options: NSKeyValueObservingOptions.New, context: nil)
    webView.addObserver(self, forKeyPath: "title", options: NSKeyValueObservingOptions.New, context: nil)
    webView.addObserver(self, forKeyPath: "URL", options: NSKeyValueObservingOptions.New, context: nil)
    webView.addObserver(self, forKeyPath: "estimatedProgress", options: NSKeyValueObservingOptions.New, context: nil)
  }


  override func viewDidDisappear(animated: Bool) {
    super.viewDidDisappear(animated)
    self.webView.stopLoading()
  }


  private func createNavigationView() {
    let closeItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Stop, target: self, action: closeButtonSelector)
    self.navigationItem.leftBarButtonItem = closeItem

    // create center view
    let titleViewWidth = self.view.frame.size.width - 100

    twoLineTitleView = UIView(frame: CGRectMake(0, 0, titleViewWidth, 44))

    titleLabel = UILabel(frame: CGRectMake(0, 6, titleViewWidth, 16))
    titleLabel?.backgroundColor = UIColor.clearColor()
    titleLabel?.font = UIFont.boldSystemFontOfSize(16)
    titleLabel?.textAlignment = NSTextAlignment.Center

    subTitleLabel = UILabel(frame: CGRectMake(0, 21, titleViewWidth, 20))
    subTitleLabel?.backgroundColor = UIColor.clearColor()
    subTitleLabel?.font = UIFont.systemFontOfSize(10)
    subTitleLabel?.textAlignment = NSTextAlignment.Center

    twoLineTitleView.addSubview(titleLabel!)
    twoLineTitleView.addSubview(subTitleLabel!)
    self.navigationItem.titleView = twoLineTitleView
  }



  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    self.webView.loadRequest(self.request)

  }


  func closeButtonTapped(sender: UIBarButtonItem) {
    self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
  }


  override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {

    if let wk = object as? WKWebView {
      switch keyPath {
      case "loading":
        if let val: AnyObject = change[NSKeyValueChangeNewKey] {
          if let val = val as? Bool {
            if val {
              self.indicator.startAnimating()
            }
            else {
              self.indicator.stopAnimating()
            }
          }
        }
      case "title":
        self.titleLabel?.text = self.webView.title
      case "URL":
        self.subTitleLabel?.text = self.webView.URL?.URLString
      case "estimatedProgress":
        println("progress: \(Int32(self.webView.estimatedProgress*100))")

      default: break
      }
    }
  }


}

Note: I use SDK iOS 8.4

注意:我使用 SDK iOS 8.4

Why does mobile Safari loads this url but WKWebViewdoes not?

为什么移动版 Safari 加载了这个 url 但WKWebView不加载?

回答by Randall Meyer

Add this to your plist

将此添加到您的 plist

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Here's the explanation for this change in 9.0 http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

这是 9.0 中此更改的解释 http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

Also if you want to set it up more secure it gives you a more complex way to do that.

此外,如果您想将其设置得更安全,它会为您提供一种更复杂的方法来做到这一点。

回答by Matthew Cawley

For me, the issue was caused by server trust check from the WKWebView.

对我来说,问题是由 WKWebView 的服务器信任检查引起的。

To fix this I had to handle the challenge authentication callback and return a server trust credential.

为了解决这个问题,我必须处理质询身份验证回调并返回服务器信任凭证。

Swift 4

斯威夫特 4

func webView(_ webView: WKWebView, 
    didReceive challenge: URLAuthenticationChallenge, 
    completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) 
{
    if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust)
    {
        let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!)
        completionHandler(.useCredential, cred)
    }
    else
    {
        completionHandler(.performDefaultHandling, nil)
    }
}

回答by saswanb

I had a similar problem with a site that was also protected with a high security TLS 1.2 certificate. To get the WKWebView to accept the server's certificate, I added this code to my web view controller delegate:

我在一个也受高安全性 TLS 1.2 证书保护的网站上遇到了类似的问题。为了让 WKWebView 接受服务器的证书,我将此代码添加到我的 Web 视图控制器委托中:

-(void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
    if ([[[challenge protectionSpace]authenticationMethod] isEqualToString: @"NSURLAuthenticationMethodServerTrust"]) {
        SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
        CFDataRef exceptions = SecTrustCopyExceptions(serverTrust);
        SecTrustSetExceptions(serverTrust, exceptions);
        CFRelease(exceptions);
        newCredential = [NSURLCredential credentialForTrust:serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential, newCredential);
    } else {
        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, newCredential);
    }
}

回答by nteissler

If you are in a sandboxed macOS app, you'll need to set the Outgoing Connections (Client) capability, you won't need to mess with Allow Abitrary Loadswhich shouldn't come into play for trusted httpsrequests. Xcode Capabilities Screenshot showing the Outgoing Connections (Client) checkbox checked

如果您使用的是沙盒 macOS 应用程序,则需要设置传出连接(客户端)功能,您将不需要弄乱不应为受信任的https请求发挥作用的Allow Abitrary LoadsXcode 功能屏幕截图显示已选中的传出连接(客户端)复选框

For iOS however, allowing client connections is the default, so you may need to implement WKNavigationDelegatemethods to handle security. Make sure you aren't just trusting untrusted certificates though. This Swift Talk video from objc.io is the best resource I know of, definitely worth 20 minutes if you're working in this area: https://talk.objc.io/episodes/S01E57-certificate-pinning

但是,对于 iOS,允许客户端连接是默认设置,因此您可能需要实现WKNavigationDelegate处理安全性的方法。不过,请确保您不只是信任不受信任的证书。这个来自 objc.io 的 Swift Talk 视频是我所知道的最好的资源,如果你在这个领域工作,绝对值得 20 分钟:https: //talk.objc.io/episodes/S01E57-certificate-pinning

回答by Ramani Hitesh

// Add plist file 
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
    <key>google.com</key>
    <dict>
        <key>NSExceptionAllowsInsecureHTTPLoads</key>
        <true/>
        <key>NSIncludesSubdomains</key>
        <true/>
    </dict>
</dict>

if WKWebView not support then declare .m file below code:

如果 WKWebView 不支持,则在代码下面声明 .m 文件:

@interface WebScannerViewController()
{

 WKWebView *webView;

}


@end



@implementation WebScannerViewController

 - (void)viewDidLoad   {

    [super viewDidLoad];
    webView.hidden=YES;

    webView.UIDelegate = self;
    webView.navigationDelegate = self;
    self.loadingSign.hidden = NO;


        webView.frame=CGRectMake(0, 94, Width, Height-128);
    }

回答by Peter Lapisu

not sure if the same error reason, but the problem was the same for me under iOS9

不知道是不是同样的错误原因,但我在iOS9下的问题是一样的

some domains couldn't be loaded

某些域无法加载

turned out that the problem was in

原来问题出在

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {

and providing back

并回馈

completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);

where I should have returned

我应该回来的地方

completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);

I was using WRONG code from https://github.com/ShingoFukuyama/WKWebViewTips

我使用了来自https://github.com/ShingoFukuyama/WKWebViewTips 的错误代码