WKWebView不加载https URL?

时间:2022-09-04 08:09:44

I have a WKWebView which should load the following url:

我有一个WKWebView,应该加载以下url:

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 WKWebView does not?

为什么移动Safari加载这个url而WKWebView不加载?

4 个解决方案

#1


20  

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.vnn5//2015/06/10/configuring-app-transportsecurity-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.

如果你想把它设置得更安全它会给你一种更复杂的方法。

#2


1  

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的错误代码

#3


1  

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 view controller委托中添加了以下代码:

-(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);
    }
}

#4


1  

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)
    }
}

#1


20  

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.vnn5//2015/06/10/configuring-app-transportsecurity-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.

如果你想把它设置得更安全它会给你一种更复杂的方法。

#2


1  

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的错误代码

#3


1  

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 view controller委托中添加了以下代码:

-(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);
    }
}

#4


1  

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)
    }
}