通过请求位于 URL 的文件/网页的标头来获取 MIMETYPE [英] Get MIMETYPE by requesting header of the file/web page reside at URL
问题描述
我需要知道文件或网页的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屋!