在 ios 中的 wkwebview 中捕获重定向 url
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45604336/
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
Capture redirect url in wkwebview in ios
提问by Prabu Raj
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. I need to capture the redirected url. Is there any method in WKNavigationDelegate to override?
如何在使用 WKWebView 时捕获重定向 url,就像网页在提交用户名和密码或其他一些数据时重定向到另一个页面一样。我需要捕获重定向的 url。WKNavigationDelegate 中是否有任何方法可以覆盖?
采纳答案by Reinier Melian
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
希望这可以帮助
回答by user2067021
(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.
使用WKNavigationDelegate
的webView(_:didReceiveServerRedirectForProvisionalNavigation:)
功能并检查WKWebView
的URL
属性。
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 时观察到的事件序列是:
The
WKNavigationDelegate
functionwebView(_:decidePolicyFor:decisionHandler:)
is called for the original URL request.WKWebView
'sURL
property is set to the original URL.The
WKNavigationDelegate
functionwebView(_:didStartProvisionalNavigation:)
is called for the original URL request.WKWebView
'sURL
property is set to the original URL.The
WKWebView
'sURL
property is updated by WebKit to the redirection URL. (You'll only know about this if you are key-value observing the property.)The
WKNavigationDelegate
functionwebView(_:decidePolicyFor:decisionHandler:)
is called for the redirected URL request.WKWebView
'sURL
property is then redirection URL.The
WKNavigationDelegate
functionwebView(_:didReceiveServerRedirectForProvisionalNavigation:)
is called.WKWebView
'sURL
property is the redirection URL.
为原始 URL 请求调用该
WKNavigationDelegate
函数webView(_:decidePolicyFor:decisionHandler:)
。WKWebView
的URL
属性设置为原始 URL。为原始 URL 请求调用该
WKNavigationDelegate
函数webView(_:didStartProvisionalNavigation:)
。WKWebView
的URL
属性设置为原始 URL。该
WKWebView
的URL
属性由WebKit的更新,以重定向URL。(只有当您是键值观察属性时,您才会知道这一点。)为重定向的 URL 请求调用该
WKNavigationDelegate
函数webView(_:decidePolicyFor:decisionHandler:)
。WKWebView
的URL
属性则是重定向 URL。该
WKNavigationDelegate
函数webView(_:didReceiveServerRedirectForProvisionalNavigation:)
被调用。WKWebView
的URL
属性是重定向 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 步颠倒了,URL
属性在 中保持不变webView(_:decidePolicyFor:decisionHandler:)
,这实际上看起来是一个合理的排序,但我没有在设备上观察到这一点。)
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 中推断出重定向,但前提是您可以确定没有其他导航更改原因。
回答by sam k
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
}
}
}
回答by JPetric
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
}
}