Cocoa中取得服务器响应头

之前有朋友问我,如果取得HTTP的服务器响应头。然后给我看了一下他的方法。是通过NSURLConnection在delegate方法connection:didReceiveResponse:里取得的,并且Request没有设定成HEAD请求。

其实在不少情况下,如果程序只是取的header不会做进一步动作。那么可以做一点优化,只做一个HEAD请求。HEAD请求
是在HTTP/1.0就定义的请求之一。而且服务器对HEAD请求响应往往更迅速。

这是一个阻塞(同步)的请求方法:

+ (NSDictionary*)queryHeaders:(NSURL*)url withTimeout:(int)sec
{
    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"HEAD"];
    [request setTimeoutInterval:sec];
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    [request addValue:USER_AGENT forHTTPHeaderField:@"User_Agent"];

    NSHTTPURLResponse *response=nil;
    NSError *error=nil;
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    if (!error && [response respondsToSelector:@selector(allHeaderFields)]) {
        return [response allHeaderFields];
    }
    return nil;
}

再给出一个非阻塞(异步)的带callback block的请求方法:

+ (void)queryHeaders:(NSURL*)url withTimeout:(int)sec callback:(void(^)(NSDictionary* headers))block
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{
        NSDictionary* headers=[[self class] queryHeaders:url withTimeout:sec];
        dispatch_async( dispatch_get_main_queue(), ^{
            block(headers);
        });
    });   
}

这2个方法,使用非常简单,放在任何一个类里都可以。

NSURL *url=[NSURL URLWithString:@"http://www.google.com"];
NSDictionary* headers=[[self class] queryHeaders:url  withTimeout:sec];
NSLog(@"headers=%@", headers);

或者

NSURL *url=[NSURL URLWithString:@"http://www.google.com"];
[[self class] queryHeaders:url withTimeout:15 callback:^(NSDictionary *headers){
    NSLog(@"headers=%@", headers);
}];

最后提一下。对于缺乏http背景知识的开发者。推荐阅读一下《TCP-IP详解》第三卷-事务协议。前2卷分别是,TCP-IP详解.卷一:协议 和 TCP-IP详解.卷二:实现。