简体   繁体   English

在 ios 中的 wkwebview 中捕获重定向 url

[英]Capture redirect url in wkwebview in ios

How do I capture the redirection url in when using WKWebView like if a webpage redirects to another page on submitting the username and password or some other data.如何在使用 WKWebView 时捕获重定向 url,就像网页在提交用户名和密码或其他一些数据时重定向到另一个页面一样。 I need to capture the redirected url.我需要捕获重定向的 url。 Is there any method in WKNavigationDelegate to override? WKNavigationDelegate 中是否有任何方法可以覆盖?

Use this WKNavigationDelegate method使用这个WKNavigationDelegate方法

public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {
        if(navigationAction.navigationType == .other) {
            if navigationAction.request.url != nil {
                //do what you need with url
                //self.delegate?.openURL(url: navigationAction.request.url!)
            }
            decisionHandler(.cancel)
            return
        }
        decisionHandler(.allow)
    }

Hope this helps希望这有帮助

(This answers the slightly more general question of how to detect a URL redirection in WKWebView, which is the search that lead me to this page.) (这回答了如何在 WKWebView 中检测 URL 重定向的更一般的问题,这是将我引导到此页面的搜索。)

Short answer简答

Use WKNavigationDelegate 's webView(_:didReceiveServerRedirectForProvisionalNavigation:) function and examine WKWebView 's URL property.使用WKNavigationDelegatewebView(_:didReceiveServerRedirectForProvisionalNavigation:) WKWebView webView(_:didReceiveServerRedirectForProvisionalNavigation:)函数并检查WKWebViewURL属性。

Longer answer更长的答案

There are a couple of places you could detect a server-side redirect.有几个地方可以检测到服务器端重定向。

On iOS 10.3.3 and iOS 11.0, the sequence of events I observe when loading a URL that gets redirected by the server is:在 iOS 10.3.3 和 iOS 11.0 上,我在加载被服务器重定向的 URL 时观察到的事件序列是:

  1. The WKNavigationDelegate function webView(_:decidePolicyFor:decisionHandler:) is called for the original URL request.为原始 URL 请求调用WKNavigationDelegate函数webView(_:decidePolicyFor:decisionHandler:) WKWebView 's URL property is set to the original URL. WKWebViewURL属性设置为原始 URL。

  2. The WKNavigationDelegate function webView(_:didStartProvisionalNavigation:) is called for the original URL request.为原始 URL 请求调用WKNavigationDelegate函数webView(_:didStartProvisionalNavigation:) WKWebView 's URL property is set to the original URL. WKWebViewURL属性设置为原始 URL。

  3. The WKWebView 's URL property is updated by WebKit to the redirection URL. WKWebViewURL属性由 WebKit 更新为重定向 URL。 (You'll only know about this if you are key-value observing the property.) (只有当您是键值观察属性时,您才会知道这一点。)

  4. The WKNavigationDelegate function webView(_:decidePolicyFor:decisionHandler:) is called for the redirected URL request.为重定向的 URL 请求调用WKNavigationDelegate函数webView(_:decidePolicyFor:decisionHandler:) WKWebView 's URL property is then redirection URL. WKWebViewURL属性则是重定向 URL。

  5. The WKNavigationDelegate function webView(_:didReceiveServerRedirectForProvisionalNavigation:) is called. WKNavigationDelegate函数webView(_:didReceiveServerRedirectForProvisionalNavigation:) WKNavigationDelegate webView(_:didReceiveServerRedirectForProvisionalNavigation:) WKWebView 's URL property is the redirection URL. WKWebViewURL属性是重定向 URL。

(Note: On the iOS 11.0 simulator I have seen steps 3 and 4 reversed, with the URL property unchanged in webView(_:decidePolicyFor:decisionHandler:) , which actually seems like a sensible ordering, but I haven't observed this on a device.) (注意:在 iOS 11.0 模拟器上,我看到第 3 步和第 4 步颠倒了,在webView(_:decidePolicyFor:decisionHandler:)URL属性没有改变,这实际上看起来是一个合理的排序,但我没有在设备。)

It seems like the webView(_:didReceiveServerRedirectForProvisionalNavigation:) is built explicitly for the purpose of detecting redirects so is probably the preferred option, although the redirect could be possibly be inferred at steps 3 or 4 but only if you can be sure that there are no other causes of navigational change.似乎webView(_:didReceiveServerRedirectForProvisionalNavigation:)是为检测重定向而明确构建的,因此可能是首选选项,尽管可能会在步骤 3 或 4 中推断出重定向,但前提是您可以确定有没有其他导航变化的原因。

After trying all the solutions, finally this one works for me using Swift 5 and WKWebView.This solution implements KVO for Swift在尝试了所有解决方案之后,最后这个解决方案对我有用 Swift 5 和 WKWebView。这个解决方案为 Swift 实现了 KVO

var webView: WKWebView?
var webViewObserver: NSKeyValueObservation?

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    webView = WKWebView(frame: self.view.bounds)
    webViewObserver = webView?.observe(\.url, options: .new, changeHandler: {
        (currentWebView, _) in
        //      Here you go the new path
        currentWebView.url
    })
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    webViewObserver?.invalidate()
}

Swift 5 Boom斯威夫特 5 繁荣

Very easy way很简单的方法

func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
    if let url = webView.url?.absoluteString{
        print("url = \(url)")
    }
}

Credits to Sven: https://forums.developer.apple.com/thread/117073归功于Sven: https : //forums.developer.apple.com/thread/117073

If you are facing a situation that your WebView doesn't open a PDF file or simply the url resolves to nothing, because the WebView's redirect URL doesn't come through you can use WKUIDelegate function webView(_:createWebViewWith:for:windowFeatures:) to capture the failed call and load the request again like:如果您遇到 WebView 无法打开 PDF 文件或 url 解析为空的情况,因为 WebView 的重定向 URL 无法通过,您可以使用WKUIDelegate函数webView(_:createWebViewWith:for:windowFeatures:)捕获失败的调用并再次加载请求,如:

extension WebViewWrapper: WKUIDelegate {

 func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
     if navigationAction.targetFrame == nil || navigationAction.targetFrame?.isMainFrame == false {
         webView.load(navigationAction.request)
     }
     return nil
 }

} }

For me, using decidePolicyFor navigation delegate's method didn't work .对我来说,使用decidePolicyFor导航委托的方法不起作用

It didn't work because WKNavigationDelegate's method它不起作用,因为 WKNavigationDelegate 的方法

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)

will only be called when there is a full-page reload.只有在重新加载整页时才会调用。 To be able to catch all WKWebView's request URL changes, a Key-Value observer will have to be placed on the WKWebView's URL property.为了能够捕获所有 WKWebView 的请求 URL 更改,必须在 WKWebView 的 URL 属性上放置一个键值观察器。

First , in viewDidLoad add:首先,在 viewDidLoad 中添加:

webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)

Second , add observeValue method、添加observeValue方法

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == #keyPath(WKWebView.url) {
            // Whenever URL changes, it can be accessed via WKWebView instance
            let url = webView.url
        }
    }

Use this WKNavigationDelegate method.使用此 WKNavigationDelegate 方法。 I got redirect url from sourceFrame.request我从 sourceFrame.request 得到了重定向 url

public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {
        let urlString = navigationAction.sourceFrame.request.url?.absoluteString ?? ""
        print("\(urlString)")
        decisionHandler(.allow)
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM