通过请求位于 URL 的文件/网页的标头来获取 MIMETYPE [英] Get MIMETYPE by requesting header of the file/web page reside at URL

查看:68
本文介绍了通过请求位于 URL 的文件/网页的标头来获取 MIMETYPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要知道文件网页MIMEType,可在特定URL处获得并根据到 MIMEType 我将决定是否将该页面/文件加载到 UIWebView 或不.我知道,我可以使用 NSURLResponse 对象获取 MIMEType,但问题是,当我收到此响应时,该页面已经下载了.

I need to know the MIMEType of the file or web page, available at particular URL and according to MIMEType I’ll take the decision whether to load that page/file to the UIWebView or not. I know, I can get MIMEType with NSURLResponse object, but problem is, when I get this response that page would have already downloaded.

那么,有什么方法可以只询问特定 URL 处的 文件/网页 的标题,以便我可以检查 MIMEType并仅在需要时才请求该页面/文件?

So, is there any way to ask only header of the file/webpage at particular URL, so that I can check the MIMEType and request for that page/file, only when it is required?

推荐答案

我看到您不希望在确定响应的 Content-Type 之前在 UIWebView 中加载页面.为此,您可以实现自定义 NSURLProtocol.这就是我所做的,但随时欢迎您增强或提出不同的解决方案.请仔细阅读内嵌评论.

I see you don't want the page to be loaded in UIWebView until you determine the Content-Type of the response. For doing this you can implement a custom NSURLProtocol. This is what I did, but you are always welcome to enhance or suggest a different solution. Please go through inline comments.

***** CustomURLProtocol.h *****

***** CustomURLProtocol.h *****

@interface CustomURLProtocol : NSURLProtocol

@end

***** CustomURLProtocol.m *****

***** CustomURLProtocol.m *****

@interface CustomURLProtocol ()

@property(nonatomic, strong) NSURLConnection * connection;
@property(nonatomic, strong) NSMutableData * reponseData;
@property(nonatomic, strong) NSURLRequest * originalRequest;

@end

@implementation CustomURLProtocol

+(BOOL)canInitWithRequest:(NSURLRequest *)request
{

    NSString * urlScheme = [request.URL.scheme lowercaseString];

    //only handling HTTP or HTTPS requests which are not being handled
    return (![[NSURLProtocol propertyForKey:@"isBeingHandled" inRequest:request] boolValue] &&
            ([urlScheme isEqualToString:@"http"] || [urlScheme isEqualToString:@"https"]));
}

+(NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
    return request;
}


-(void)startLoading
{
    NSMutableURLRequest * requestCopy = [self.request mutableCopy];
    [NSURLProtocol setProperty:[NSNumber numberWithBool:YES] forKey:@"isBeingHandled" inRequest:requestCopy];
    self.originalRequest = requestCopy;
    self.connection = [NSURLConnection connectionWithRequest:requestCopy delegate:self];
}

-(void)stopLoading
{
    [self.connection cancel];
}

#pragma mark - NSURLConnectionDelegate methods


-(NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
{

    [self.client URLProtocol:self wasRedirectedToRequest:request redirectResponse:response];

    return request;
}



- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    if ([response isKindOfClass:[NSHTTPURLResponse class]])
    {
        NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;
        NSString * contentType = [httpResponse.allHeaderFields valueForKey:@"Content-Type"];

        /*
         Check any header here and make the descision.
         */
        if([contentType containsString:@"application/pdf"])
        {

            /*
                Let's say you don't want to load the PDF in current UIWebView instead you want to open another view controller having a webview for that.
                For doing that we will not inform the client about the response we received from NSURLConnection that we created.
             */

            [self.connection cancel];

            //post a notification carrying the PDF request and load this request anywhere else.
            [[NSNotificationCenter defaultCenter] postNotificationName:@"PDFRequest" object:self.originalRequest];
        }
        else
        {
            /*
                For any other request having Content-Type other than application/pdf,
                we are informing the client (UIWebView or NSURLConnection) and allowing it to proceed.
             */
            [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
        }
    }

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.client URLProtocol:self didLoadData:data];
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

    [self.client URLProtocolDidFinishLoading:self];
}

- (void)connection:(NSURLConnection *)connectionLocal didFailWithError:(NSError *)error
{
    [self.client URLProtocol:self didFailWithError:error];
}

@end

我忘记提及的另一件事是您必须在您的应用委托中注册 CustomURLProtocol,如下所示:

One more thing which I forgot to mention is that you have to register the CustomURLProtocol in your app delegate like below:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   [NSURLProtocol registerClass:[CustomURLProtocol class]];
    return YES;
}

这篇关于通过请求位于 URL 的文件/网页的标头来获取 MIMETYPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆