我通过WebView管理授权逻辑:
我在WebView委托方法shouldStartLoadWithRequest:
中检查所有请求(以捕获redirect_uri)。
问题:如何管理WebView中打开的每个页面请求的服务器响应?
关键是我们在auth服务器上遇到一些问题,并且不时显示错误页面。所以我想抓住这些页面并关闭WebView以获取此类案例。
答案 0 :(得分:3)
通过WKWebView
找到解决方案。
我以与UIWebView
在我的项目中工作相同的方式连接它。
然后我实际使用了来自WKNavigationDelegate
协议的两种方法:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
和
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
代码示例:
第一种方法是检查当前请求是否实际上是我们应该处理的redirect_uri
:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSLog(@"request: %@", navigationAction.request);
// check whether this request should be stopped - if this is redirect_uri (like user is already authorized)
if (...) {
self.webView.navigationDelegate = nil;
// do what is needed to send authorization data back
self.completionBlock(...);
// close current view controller
[self dismissViewControllerAnimated:YES completion:nil];
// stop executing current request
decisionHandler(WKNavigationActionPolicyCancel);
} else {
// otherwise allow current request
decisionHandler(WKNavigationActionPolicyAllow);
}
}
第二种方法是分析来自服务器的响应,在这里我们可以验证状态代码以便处理任何错误
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
// filter the responses, in order to verify only the response from specific domain
if ([[NSString stringWithFormat:[[response URL] absoluteString]] containsString:@"some.domain.com/"]) {
NSInteger statusCode = [response statusCode];
// check what is the status code
if (statusCode == 200 ||
statusCode == 301 ||
statusCode == 302) {
// allow response as everything is ok
decisionHandler(WKNavigationResponsePolicyAllow);
} else {
// handle the error (e.g. any of 4xx or any others)
self.webView.navigationDelegate = nil;
// send needed info back
self.completionBlock(...);
// close current view controller
[self dismissViewControllerAnimated:YES completion:nil];
// stop current response
decisionHandler(WKNavigationResponsePolicyCancel);
}
} else {
// current response is not from our domain, so allow it
decisionHandler(WKNavigationResponsePolicyAllow);
}
}
答案 1 :(得分:0)
实施以下委托方法可能适合您。
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSCachedURLResponse *urlResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:webView.request];
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) urlResponse.response;
NSInteger statusCode = httpResponse.statusCode;
NSLog(@"%@",statusCode);
}
答案 2 :(得分:0)
在 swift 中,您可以尝试将 URLResponse 转换为 HTTPURLResponse 以获取 statusCode 字段。
extension MyController: WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse,
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
if let httpResponse = navigationResponse.response as? HTTPURLResponse {
let statusCode = httpResponse.statusCode
//....
}
decisionHandler(.allow)
}
}