如何获取HTTP标头

Nag*_*gra 28 http objective-c uiwebview uiwebviewdelegate

如何从NSURLRequestObjective-C中检索所有HTTP头?

Har*_*ran 38

这属于容易但不明显的iPhone编程问题.值得一个快速的帖子:

HTTP连接的标头包含在NSHTTPURLResponse类中.如果你有一个NSHTTPURLResponse变量,你可以NSDictionary通过发送allHeaderFields消息轻松地将标题输出.

对于同步请求 - 不推荐,因为它们阻止 - 很容易填充NSHTTPURLResponse:

NSURL *url = [NSURL URLWithString:@"http://www.mobileorchard.com"];
NSURLRequest *request = [NSURLRequest requestWithURL: url];
NSHTTPURLResponse *response;
[NSURLConnection sendSynchronousRequest: request returningResponse: &response error: nil];
if ([response respondsToSelector:@selector(allHeaderFields)]) {
NSDictionary *dictionary = [response allHeaderFields];
NSLog([dictionary description]);
}
Run Code Online (Sandbox Code Playgroud)

使用异步请求,您需要做更多的工作.调用回调时connection:didReceiveResponse:,它将NSURLResponse作为第二个参数传递给它.你可以把它变成NSHTTPURLResponse这样:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
 NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;    
if ([response respondsToSelector:@selector(allHeaderFields)]) {
    NSDictionary *dictionary = [httpResponse allHeaderFields];
    NSLog([dictionary description]);
}
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您只想获取http响应标头,则发布HEAD请求.HEAD请求不会获取响应体.示例 - 在请求中设置Http方法类型.NSMutableURLRequest*mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url]; mutableRequest.HTTPMethod = @"HEAD"; (3认同)
  • 这不会*不*记录请求中发送的所有标头!如果您为 NSURLSessionConfiguration 设置了其他标头,则不会记录这些标头。我还没有找到如何从响应中检索它们... (3认同)

use*_*021 5

鉴于NSURLConnectioniOS 9已弃用,您可以使用NSURLSessionNSURL或获取MIME类型信息NSURLRequest

您要求会话检索URL,然后在NSURLResponse委托回调中接收到第一个会话(包含MIME类型信息)后,取消会话以防止其下载整个URL。

这是一些简单的Swift代码:

/// Use an NSURLSession to request MIME type and HTTP header details from URL.
///
/// Results extracted in delegate callback function URLSession(session:task:didCompleteWithError:).
///
func requestMIMETypeAndHeaderTypeDetails() {
    let url = NSURL.init(string: "https://google.com/")
    let urlRequest = NSURLRequest.init(URL: url!)

    let session = NSURLSession.init(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration(), delegate: self, delegateQueue: NSOperationQueue.mainQueue())

    let dataTask = session.dataTaskWithRequest(urlRequest)
    dataTask.resume()
}

//MARK: NSURLSessionDelegate methods

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {

    // Cancel the rest of the download - we only want the initial response to give us MIME type and header info.
    completionHandler(NSURLSessionResponseDisposition.Cancel)
}

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?)
{       
    var mimeType: String? = nil
    var headers: [NSObject : AnyObject]? = nil


    // Ignore NSURLErrorCancelled errors - these are a result of us cancelling the session in 
    // the delegate method URLSession(session:dataTask:response:completionHandler:).
    if (error == nil || error?.code == NSURLErrorCancelled) {

        mimeType = task.response?.MIMEType

        if let httpStatusCode = (task.response as? NSHTTPURLResponse)?.statusCode {
            headers = (task.response as? NSHTTPURLResponse)?.allHeaderFields

            if httpStatusCode >= 200 && httpStatusCode < 300 {
                // All good

            } else {
                // You may want to invalidate the mimeType/headers here as an http error
                // occurred so the mimeType may actually be for a 404 page or
                // other resource, rather than the URL you originally requested!
                // mimeType = nil
                // headers = nil
            }
        }
    }

    NSLog("mimeType = \(mimeType)")
    NSLog("headers = \(headers)")

    session.invalidateAndCancel()
}
Run Code Online (Sandbox Code Playgroud)

我已经在github 的URLEnquiry项目中打包了类似的功能,这使得对MIME类型和HTTP标头进行内联查询变得容易一些。URLEnquiry.swift是感兴趣的文件,可以放入您自己的项目中。