Jak odzyskać wszystkie nagłówki HTTP z NSURLRequest
w Objective-C?Jak uzyskać nagłówki HTTP
Odpowiedz
ta podlega łatwe, ale nie oczywista klasa problemów programowania iPhone. Warto szybki post:
Nagłówki połączenia HTTP są zawarte w klasie NSHTTPURLResponse
. Jeśli masz zmienną NSHTTPURLResponse
, możesz łatwo uzyskać nagłówki jako NSDictionary
, wysyłając wiadomość allHeaderFields.
synchronicznych żądań - nie zalecane, ponieważ blokują - to proste do wypełnienia się 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]);
}
Z asynchronicznego żądania trzeba zrobić trochę więcej pracy. Po wywołaniu wywołania zwrotnego connection:didReceiveResponse:
jako drugi parametr przekazuje się NSURLResponse
. można oddać go do NSHTTPURLResponse
tak:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
NSDictionary *dictionary = [httpResponse allHeaderFields];
NSLog([dictionary description]);
}
}
YourViewController.h
@interface YourViewController : UIViewController <UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *yourWebView;
@end
YourViewController.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]);
}
Biorąc NSURLConnection
jest przestarzała z iOS 9, można użyć, aby uzyskać informacje NSURLSession
typu MIME z NSURL
lub NSURLRequest
.
Pytasz sesję, aby pobrać adres URL, a po otrzymaniu pierwszego NSURLResponse
(który zawiera informacje typu MIME) w delegowanym oddzwonieniu anulujesz sesję, aby uniemożliwić pobranie całego adresu URL.
Oto niektóre szkielety Swift kod, który to robi:
/// 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()
}
mam zapakowane podobną funkcjonalność w projekcie URLEnquiry na github, który sprawia, że nieco łatwiej zapytań w linii dla typów MIME i Nagłówki HTTP. URLEnquiry.swift to plik zainteresowania, który można przenieść do własnego projektu.
Wersja Swift z wykorzystaniem Alamofire dla zwiększenia wydajności. To właśnie zadziałało:
Alamofire.request(YOUR_URL).responseJSON {(data) in
if let val = data.response?.allHeaderFields as? [String: Any] {
print("\(val)")
}
}
Jeśli chcesz tylko pobrać nagłówek odpowiedzi http, a następnie wysłać żądanie HEAD. Żądanie HEAD nie pobiera treści odpowiedzi. Przykład - Ustaw typ metody Http w żądaniu. NSMutableURLRequest * mutableRequest = [[NSMutableURLRequest alloc] initWithURL: url]; mutableRequest.HTTPMethod = @ "HEAD"; – Omkar
Dlaczego powinniśmy rzucić NSURLResponse na NSHTTPURLResponse? – youssman
Dzięki temu * nie * zaloguj się wszystkie nagłówki wysłane w żądaniu! Jeśli ustawisz dodatkowe nagłówki na NSURLSessionConfiguration, te nie będą rejestrowane. Nie znalazłem jeszcze sposobu odzyskania ich z odpowiedzi ... – Johanneke