zoukankan      html  css  js  c++  java
  • UIWebView处理authentication方法

    在用UIWebView的时候,如果访问需要http authentication,那么网页将无法显示。原因是UIWebView不会检测到网络设置,如代理设置,需要http认证等。

    首先我们来说一下网络在代理环境中的authentication,如何让UIWebView正常工作

    由于UIWebView不会自动检测代理设置,所以解决方法是在UIWebViewDelegate方法中用NSURLConnect去连接到网络中任一网站,在NSURLConnectionDelegate接口中处理代理设置,在这儿需要代理用户名与密码。步骤如下:

    1. 用NSURLConnect连接任一网站

    1. NSURLRequest *req = [NSURLRequest requestWithURL:url  
    2.                                              cachePolicy:NSURLRequestReloadIgnoringCacheData  
    3.                                          timeoutInterval:20.0];  
    4. [[NSURLConnection alloc] initWithRequest:req delegate:self];  


    2. connection:didReceiveAuthenticationChallenge方法中处理代理设置

    1. - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;  
    2. {     
    3.         //如果是http代理,其它代理方法类似  
    4.     if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLProtectionSpaceHTTPProxy])  
    5.     {  
    6.           
    7.         if ([challenge previousFailureCount] == 0) {  
    8.             /* SET YOUR credentials, i'm just hard coding them in, tweak as necessary */  
    9.             [[challenge sender] useCredential:[NSURLCredential credentialWithUser:AUTH_USERNAME password:AUTH_PASSWORD persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge];  
    10.         } else {  
    11.             [[challenge sender] cancelAuthenticationChallenge:challenge];   
    12.         }  
    13.     }  
    14. }  


    这下你的代理设置就保存了,因为用的是NSURLCredentialPersistencePermanent,以后在用UIWebView的时候就可以正常显示内容了。

    更为完美的解决方案是NSURLProtocol参看:http://kadao.dir.bg/cocoa.htm

    还有一种方法就是用ASIHttpRequest,开启

    1. request.shouldPresentProxyAuthenticationDialog = YES;  
    2. [request setUseKeychainPersistence:YES];  


    这样detect到代理的时候就会弹出输入框加要用户输入用户名与密码,且保存在keychain里,下次运行不需要再输 。

    接着我们来说一下如果网站需要http basic authentication,如何让UIWebView正常工作

    经过google我发现了下面这种方法:

    需要http认证,其实就是在每次请求的时候需要在http头加入用户名与密码,保证这次请求的合法性。最开始的时候,我也是采用上面的方法,就是每次UIWebView开始请求的时候先用NSURLConnect去连接这个请求,在其 connection:didReceiveAuthenticationChallenge方法中处理用户名与密码。这种处理方法会两次访问同一个url且速度很慢。然后我就用了新的方法,即在NSURLRequest中加入Authorization字段,代码如下:

    1. NSURL *url = [NSURL URLWithString:yourUrlStr];      
    2. NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];  
    3. NSString *authString = [[[NSString stringWithFormat:@"%@:%@", username, password] dataUsingEncoding:NSUTF8StringEncoding] base64Encoding];  
    4.       
    5. authString = [NSString stringWithFormat: @"Basic %@", authString];  
    6.       
    7. [req setValue:authString forHTTPHeaderField:@"Authorization"];  

    其中username与password就是需要的用户名与密码。

    网上有人写了一个NSMutableURLRequest的category,用起来也方便,随便也分享给大家。https://github.com/oscardelben/UIWebViewBasicAuth

    在这儿我们得注意了:在头中加Authorization字段,我在iOS5中测试了, 通过这种方式request的UIWebView是不能成功显示网页的。没有iOS3与4测试,我猜测是以前的OS可以用这种方法。但是如果用NSURLConnection去request,这种方法是可行的,能返回正确的html,但是image这些不能显示。UIWebView是基于NSURL loading system的,理论上应是可行的,但是测试结果是不行。

    即然这种方法不适用,那就得另寻方法。经过在网上找资料发现,如果把用户名与密码写在url里,那么就可以在UIWebView中正常访问。代码如下:

    1. NSString *URLString = [[NSString stringWithFormat:@"http://%@:%@@%@", @"username", @"password", [urlStr substringFromIndex:7]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];  
    2. NSURL *url = [NSURL URLWithString:URLString];  
    3. NSURLRequest *req = [NSURLRequest requestWithURL:url  
    4.                                      cachePolicy:NSURLRequestReloadIgnoringCacheData  
    5.                                  timeoutInterval:20.0];  
    6. webView loadRequest:req];  

    我在iPad1上测试可行,iPhone4上行,iPad与iPhone模拟器上都行,在iPad2上测试则不行,OS都是iOS5.

    接在我在研究能通用方法,就是NSURL loading system。还在研究当中,有结果了再公布。

    有了上面两种方法介绍,那么在有代理网络环境下去访问需要用户名与密码认识的网站,就可以完全正常了。

    ASIWebPageRequest也是一个不错的选择,可以同时处理proxy与Http Basic Authentication。

    参考:

    http://www.springenwerk.com/2008/11/i-am-currently-building-iphone.html

    http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html

  • 相关阅读:
    转 方法多态与Duck typing;C#之拙劣与F#之优雅
    Steve Jobs explains objectoriented programming
    c# 之 dynamic关键字
    Eric Schmidt 之关于 Steve Jobs
    面向过程vs面向对象
    转 命令,不要去询问(Tell, Don’t Ask)
    转 函数式编程的10年演化:越来越纯
    网络流学习笔记——简单题
    网络流学习笔记——难题
    线性代数学习笔记
  • 原文地址:https://www.cnblogs.com/greywolf/p/2832479.html
Copyright © 2011-2022 走看看