0
回答
UIWebView处理authentication方法
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

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

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

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

1. 用NSURLConnect连接任一网站

NSURLRequest *req = [NSURLRequest requestWithURL:url
											 cachePolicy:NSURLRequestReloadIgnoringCacheData
										 timeoutInterval:20.0];
[[NSURLConnection alloc] initWithRequest:req delegate:self];

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

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

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

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

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

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

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


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

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

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

NSURL *url = [NSURL URLWithString:yourUrlStr];    
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *authString = [[[NSString stringWithFormat:@"%@:%@", username, password] dataUsingEncoding:NSUTF8StringEncoding] base64Encoding];
    
authString = [NSString stringWithFormat: @"Basic %@", authString];
    
[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中正常访问。代码如下:

	NSString *URLString = [[NSString stringWithFormat:@"http://%@:%@@%@", @"username", @"password", [urlStr substringFromIndex:7]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
	NSURL *url = [NSURL URLWithString:URLString];
	NSURLRequest *req = [NSURLRequest requestWithURL:url
										 cachePolicy:NSURLRequestReloadIgnoringCacheData
									 timeoutInterval:20.0];
[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





原文链接:http://blog.csdn.net/favormm/article/details/6956588
<无标签>
举报
长平狐
发帖于5年前 0回/119阅
顶部