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
WKWebView does not load https URL?
提问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 WKWebView
does 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.
如果您使用的是沙盒 macOS 应用程序,则需要设置传出连接(客户端)功能,您将不需要弄乱不应为受信任的https请求发挥作用的Allow Abitrary Loads。
For iOS however, allowing client connections is the default, so you may need to implement WKNavigationDelegate
methods 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