重定向与转发经常不明白是什么意思
现在来解释一下:
请求重定向相当于是重新发送了一次请求,而请求转发是一次请求;
1>请求重定向:就好比我们找一个A广告公司给设计名片,A明确告诉我们他们不会设计,就让我们找B公司,结果B公司给我设计好了,所以我们会对外宣称是B公司给我们设计的名片,(所以我们就相当于发送了两次次请求,URL地址栏里就从A变成了B公司)
一、ios webview怎么判断http是重定向
public boolean shouldOverrideUrlLoading (WebView view, String url) {
HitTestResult hit = view.getHitTestResult();
if (hit != null) {
Intent intent = new Intent();
intent.setAction( "android.intent.action.VIEW");
Uri content_url = Uri. parse(url);
intent.setData(content_url);
context.startActivity(intent);
return true;
} else {
view.loadUrl(url);
return true;
}
}
二、iOS应用中URL地址如何重定向
例如http://www.google.com谷歌的首页
大家都知道现在浏览器中打开google.com的话事实上会变成http://www.google.com.hk。显然是网址被重定向的结果
如何在app中完成重定向呢
使用NSURLConnetion类的NSURLConnectionDataDelegate委托
NSURLConnectionDataDelegate委托中的这个方法
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (!connection) {
NSLog(@"FAIL");
}
}
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
NSLog(@"====================================");
NSLog(@"will send request\n%@", [request URL]);
NSLog(@"redirect response\n%@", [response URL]);
return request;
}
委托方法在请求将要被发送出去之前就会调用
返回值是一个NSURLRequest即那个真正将要被发送的请求
第二个参数request就是被重定向处理过后的请求 在这里就可以拿到需要的URL
第三个参数response是一个将要触发重定向的请求
这里把request跟response中的URL打出来看一下
====will send request====
http://www.google.com/
====redirect response====
(null)
====will send request====
http://www.google.com.hk/url?sa=p&hl=zh-CN&pref=hkredirect&pval=yes&q=http://www.google.com.hk/&ust=1347589441099727&usg=AFQjCNEsBYcrlh_jqpBWRwsc0NpBj2_lFg
====redirect response====
http://www.google.com/
====will send request====
http://www.google.com.hk/
====redirect response====
http://www.google.com.hk/url?sa=p&hl=zh-CN&pref=hkredirect&pval=yes&q=http://www.google.com.hk/&ust=1347589441099727&usg=AFQjCNEsBYcrlh_jqpBWRwsc0NpBj2_lFg
由以上结果可知:
<1> 第一次调用 没有进行重定向处理 所以redirect response是null
而想要被发送的请求就是www.google.com
<2> 第二次redirect response就不是null了,就是第一次中的那个request,也就是说这一次的重定向是由www.google.com这个URL引发的
而重定向的结果就是http://www.google.com.hk/url?sa=p&hl=zh-CN&pref=hkredirect&pval=yes&q=http://www.google.com.hk/&ust=1347589441099727&usg=AFQjCNEsBYcrlh_jqpBWRwsc0NpBj2_lFg
<3> 当然http://www.google.com.hk/url?sa=p&hl=zh-CN&pref=hkredirect&pval=yes&q=http://www.google.com.hk/&ust=1347589441099727&usg=AFQjCNEsBYcrlh_jqpBWRwsc0NpBj2_lFg这个网址不是那个熟悉的网址,因为还要一次重定向,这次就跟上面一样了 那个很长的URL这次出现在了redirect response里,触发了这次重定向
结果可以看到,就是那个熟悉的www.google.com.hk
<4> 当获得想要的URL以后可以调用[connection cancel];方法来取消连接
并返回nil就好了
三、IOS拦截重定向请求(302)的几种方式
在多数情况下,我们做的网络请求是返回200状态码的,但也有返回302的时候,比如使用基于Oauth2认证协议的API时,在认证阶段,需要提供一个回调地址,当用户授权后,服务器会返回一个302 Response,Response Header中会一个Location字段,包含了我们的回调地址,同时会有一个Code参数。我们在程序中该如何处理这个请求,并拿到这个Code参数呢。下面由我来为大家讲解下几种方式的做法,各取所需。
《1》UIWebView控件
这是最常见的做法,但是UIWebView是无法拦截302请求的,只能等待整个流程完成回到回调地址时,我们在webView控件的webViewDidFinishLoad回调方法处理数据。
《2》基于NSURLConnection来设置拦截
class LoginViewController: UIViewController,NSURLConnectionDataDelegate {
func connection(){
//创建一个可以编辑的NSURLRequest
var mutableRequest = NSMutableURLRequest(URL: NSURL(string: "http://devonios.com")!)
mutableRequest.HTTPMethod = "POST"
//设置POST请求的表单数据
mutableRequest.HTTPBody = paramString.dataUsingEncoding(NSStringEncoding.allZeros, allowLossyConversion: true)
//使用构造函数方法创建一个NSURLConnection的实例
var connection:NSURLConnection = NSURLConnection(request: mutableRequest, delegate: self)!
connection.start()
}
//处理重定向请求的方法
func connection(connection: NSURLConnection, willSendRequest request: NSURLRequest, redirectResponse response: NSURLResponse?) -> NSURLRequest? {
if let r = response{
//当前重定向请求的url,包含了Code参数
let requesturl = request.URLString
//得到Code,由于Code参数设置了属性观察器,所以当Code被赋值时,会自动去获取Token
self.code = requesturl.GetCode()
//因为已经拿到Code了,所以拦截掉当前这个重定向请求,直接返回nil
return nil
}
return request
}
//整个请求完成后,即拦截到302后,不再请求了就返回这里
func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse) {
if (某些判断条件){
self.navigationController?.popViewControllerAnimated(true)
}
}
}
《3》基于NSURLSession类来设置拦截
NSURLSession是IOS 7中开始出现的全新的网络接口类,和NSURLConnection类似,同样需要设置delegate。
class MyRequestController:NSObject,NSURLSessionTaskDelegate {
let session:NSURLSession?
init(){
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
session = NSURLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
}
deinit{
session!.invalidateAndCancel()
}
//处理重定向请求,直接使用nil来取消重定向请求
func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: (NSURLRequest!) -> Void) {
completionHandler(nil)
}
func sendRequest() {
var URL = NSURL(string: "http://devonios.com")
let request = NSMutableURLRequest(URL: URL!)
request.HTTPMethod = "POST"
request.HTTPBody = paramString.dataUsingEncoding(NSStringEncoding.allZeros, allowLossyConversion: true)
let task = session!.dataTaskWithRequest(request, completionHandler: { (data : NSData!, response : NSURLResponse!, error : NSError!) -> Void in
//由于拦截了302,设置了completionHandler参数为nil,所以忽略了重定向请求,这里返回的Response就是包含302状态码的Response了。
let resp:NSHTTPURLResponse = response as! NSHTTPURLResponse
println("包含302状态的Response Header字段 : \(resp.allHeaderFields)") })
task.resume()
}
}
目前为止,我们通过为NSURLConnection或者NSURLSession设置一个Delegate,通过回调方法来拦截(其实就是返回个nil)。
参考资料http://devonios.com/intercept-302-request.html