30

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

4

5 回答 5

42

这属于简单但不明显的 iPhone 编程问题。值得快速发帖:

HTTP 连接的标头包含在NSHTTPURLResponse该类中。如果您有一个变量,您可以通过发送 allHeaderFields 消息NSHTTPURLResponse轻松地将标头作为 a取出。NSDictionary

对于同步请求——不推荐,因为它们会阻塞——很容易填充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]);
}

对于异步请求,您必须做更多的工作。当回调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]);
}
}
于 2012-11-05T17:03:01.913 回答
5

GivenNSURLConnection已从 iOS 9 中弃用,您可以使用 anNSURLSessionNSURLor获取 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()
}

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

于 2016-04-12T03:58:59.620 回答
2

你的ViewController.h

@interface YourViewController : UIViewController <UIWebViewDelegate>
    @property (weak, nonatomic) IBOutlet UIWebView *yourWebView;
@end

你的视图控制器.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    //Set the UIWebView delegate to your view controller
    self.yourWebView.delegate = self;

    //Request your URL
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://website.com/your-page.php"]];

    [self.legalWebView loadRequest:request];
}

//Implement the following method
- (void)webViewDidFinishLoad:(UIWebView *)webView{
    NSLog(@"%@",[webView.request allHTTPHeaderFields]);
}
于 2012-11-05T16:33:38.810 回答
2

使用 Alamofire 提高效率的 Swift 版本。这对我有用:

Alamofire.request(YOUR_URL).responseJSON {(data) in

if let val = data.response?.allHeaderFields as? [String: Any] {
      print("\(val)")
    }
}
于 2017-04-24T00:20:31.780 回答
0

您可以使用 AFHTTPSessionManager 框架并在请求之后或期间获取标头,例如下面的示例(获取所有密钥):

NSHTTPURLResponse *reponse = (NSHTTPURLResponse *)task.response; NSLog(@"%@", [reponseHeaders allHeaderFields]);

访问特定键:[reponseHeaders allHeaderFields][@"someKey"]

参考: https ://github.com/AFNetworking/AFNetworking/issues/3688

于 2020-02-04T20:08:21.737 回答