现在我正在使用canInitWithRequest:
和NSURLProtocol
WKWebView
我可以拦截所有请求并按照我想要的方式使用它。
在新的enum MyEnum {
FIRST
{
@Override
void foo() {
//Do something
}
},
SECOND
{
@Override
void foo() {
//Do something else
}
};
abstract void foo();
}
这个方法中没有,我没有找到类似的东西。
有人解决了这个问题吗?
答案 0 :(得分:1)
WKWebView提出了名为 WKURLSchemeHandler 的自定义方案处理程序,您可以使用它来拦截自定义事件。 有关更多信息,请查看此项目。 https://github.com/BKRApps/KRWebView
答案 1 :(得分:1)
您可以通过为decidePolicyFor: navigationAction:
实现WKNavigationDelegate
方法,在iOS 8.0以后的WKWebView上拦截请求。
func webView(_ webView: WKWebView, decidePolicyFor
navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {
//link to intercept www.example.com
// navigation types: linkActivated, formSubmitted,
// backForward, reload, formResubmitted, other
if navigationAction.navigationType == .linkActivated {
if webView.url!.absoluteString == "http://www.example.com" {
//do stuff
//this tells the webview to cancel the request
decisionHandler(.cancel)
return
}
}
//this tells the webview to allow the request
decisionHandler(.allow)
}
答案 2 :(得分:1)
有很多方法可以实现拦截器请求。
设置本地代理,使用WKNavigationDelegate
-[ViewController webView:decidePolicyForNavigationAction:decisionHandler:]
加载新请求并转发到本地服务器,您可以在本地服务器端执行某些操作(例如缓存)。
私有api。使用WKBrowsingContextController和自定义URLProtocol
Class cls = NSClassFromString(@"WKBrowsingContextController");
SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:");
if ([(id)cls respondsToSelector:sel]) {
// 把 http 和 https 请求交给 NSURLProtocol 处理
[(id)cls performSelector:sel withObject:@"http"];
[(id)cls performSelector:sel withObject:@"https"];
}
使用KVO获取系统http / https处理程序。(ios 11,*)
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
URLSchemeHandler *schemeHandler = [[URLSchemeHandler alloc] init];
[configuration setURLSchemeHandler:schemeHandler forURLScheme:@"test"];
NSMutableDictionary *handlers = [configuration valueForKey:@"_urlSchemeHandlers"];
handlers[@"http"] = schemeHandler;
handlers[@"https"] = schemeHandler;
您可能需要用所有三种方式处理CORS和要剥离的正文,您覆盖更改浏览器的选项请求( Preflighted_requests),您可以自定义http标头以替换http正文以删除帖子正文。
答案 3 :(得分:1)
我知道我来晚了,但是我能够解决这个问题。我可以使用以下技巧来拦截每个请求,甚至您的http / https呼叫。我还可以跟踪从html到服务器的调用。我还可以使用它来呈现带有脱机内容的html。
let configuration = WKWebViewConfiguration();
configuration.setURLSchemeHandler(self, forURLScheme: "myhandler-webview");
webView = WKWebView(frame: view.bounds, configuration: configuration);
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
var htmlURL = URL(fileURLWithPath: htmlPath!, isDirectory: false)
htmlURL = self.changeURLScheme(newScheme: "myhandler-webview", forURL: htmlURL)
self.webView.load(URLRequest(url: htmlURL))
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
print("Function: \(#function), line: \(#line)")
print("==> \(urlSchemeTask.request.url?.absoluteString ?? "")\n")
// You can find the url pattern by using urlSchemeTask.request.url. and create NSData from your local resource and send the data using 3 delegate method like done below.
// You can also call server api from this native code and return the data to the task.
// You can also cache the data coming from server and use it during offline access of this html.
// When you are returning html the the mime type should be 'text/html'. When you are trying to return Json data then we should change the mime type to 'application/json'.
// For returning json data you need to return NSHTTPURLResponse which has base classs of NSURLResponse with status code 200.
// Handle WKURLSchemeTask delegate methods
let url = changeURLScheme(newScheme: "file", forURL: urlSchemeTask.request.url!)
do {
let data = try Data(contentsOf: url)
urlSchemeTask.didReceive(URLResponse(url: urlSchemeTask.request.url!, mimeType: "text/html", expectedContentLength: data.count, textEncodingName: nil))
urlSchemeTask.didReceive(data)
urlSchemeTask.didFinish()
} catch {
print("Unexpected error when get data from URL: \(url)")
}
}
func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
print("Function: \(#function), line: \(#line)")
print("==> \(urlSchemeTask.request.url?.absoluteString ?? "")\n")
}
让我知道这个解释是否还不够。
下面提到的客观c示例
答案 4 :(得分:1)
我发现这个问题在 5 年后仍然会引起好奇心,所以我描述了我是如何解决它的以及我面临的一些主要问题。
正如在此回答的许多人一样,我已经实施了 WKURLSchemeHandler
并使用了新方案。
首先,wkwebview 启动的 URL 不能是 HTTP(或 HTTPS),而是您的新方案之一。
示例
mynewscheme://your-server-application.com
在您的 WKWebViewConfiguration
conf 中,我设置了处理程序:
[conf setURLSchemeHandler:[CustomSchemeHandler new] forURLScheme:@"mynewscheme"];
[conf setURLSchemeHandler:[CustomSchemeHandler new] forURLScheme:@"mynewschemesecure"];
在 CustomSchemeHandler
中,我实现了 webView:startURLSchemeTask:
和 webView:stopURLSchemeTask:
。
在我的情况下,我检查请求是否针对我刚刚保存在本地的文件,否则我使用 http(或 https)更改实际协议(“mynewscheme 或“mynewschemesecure”),然后我自己提出请求。
此时我解决了“拦截问题”。
以这种新方式,我们在我的新方案中获得了 webview“位置”(location.href
,通过 javascript),随之而来的是新的问题。
第一个问题是我的应用程序主要使用 javascript,
并且 document.cookie
已停止工作。我正在使用科尔多瓦
框架,所以我开发了一个插件来设置和获取 cookie
替换 document.cookie(我必须这样做,因为,显然,我
也有 http 标头 set-cookie)。
第二个问题是我有很多“跨域”问题,然后 我更改了相对网址中的所有网址(或使用新方案)
第三个问题是浏览器自动处理服务器80端口 和 443,省略它们,但现在已经停止(可能是因为“不 http 位置”)。在我的服务器代码中,我必须处理这个问题。
写下这几行我承认这似乎是一个容易解决的问题,但我确保找到解决方法,如何解决它并与无限量的代码集成一直很困难。解决方案的每一步都对应着一个新问题。
答案 5 :(得分:0)
我盲目地猜测,因为我只有我的Windows电脑。通过阅读Apple Developer文档,我收集的信息可能会带来一些关于如何解决问题的想法。
基于WKWebView,
将delegate属性设置为符合WKUIDelegate协议的对象,以跟踪Web内容的加载。
另外,我发现我们可以使用
设置navigationDelegate
weak var navigationDelegate: WKNavigationDelegate? { get set }
WKNavigationDelegate协议的方法可帮助您实现在Web视图接受,加载和完成导航请求的过程中触发的自定义行为。
然后在我们创建并设置自定义WKNavigationDelegate之后,我们将覆盖一些方法来拦截我们可能正在寻找的东西。我找到了一些感兴趣的Responding to Server Actions部分,因为他们收到WKNavigation作为参数。此外,您可能希望浏览WKNavigationAction和WKNavigationResponse,看看是否有某些内容可能有助于我们实现目标。
顺便说一下,我只想提出一些想法,以便我们可以解决这个问题,这些想法可能100%错误,因为我自己没有尝试过。答案 6 :(得分:0)
一个人可以使用WKURLSchemeHandler来拦截要加载到WKWebView中的每个请求, 唯一的缺点是您无法注册用于拦截的http或https方案,
解决方案是 用自定义方案网址(例如xyz://)替换您的http / https方案网址 例如https://google.com可以像xyz://google.com一样加载 现在,您将在WKURLSchemeHandler中获得一个回调,然后再次将其替换回https并以编程方式加载数据并调用urlSchemeTask.didReceive(response)
这样,每个https请求都会到达您的处理程序。