如何获取 cookie 并将它们用于其他请求,如 POST ( iOS )?
Posted
技术标签:
【中文标题】如何获取 cookie 并将它们用于其他请求,如 POST ( iOS )?【英文标题】:How to get cookies and use them for other requests like POST ( iOS )? 【发布时间】:2012-09-22 18:20:22 【问题描述】:我的previous question 是关于我每次都必须登录才能进行网络服务(例如发布链接或上传图片)的问题。 Philipe 回答说我必须为每个请求使用 cookie 而不是登录过程。我找到了这种获取 cookie 的方法:
- (void)getCookies
NSHTTPURLResponse * response;
NSError * error;
NSMutableURLRequest *request;
request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://MyWebsite.com/login.php"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:120];
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
NSArray * all = [NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:[NSURL URLWithString:@"http://MyWebsite.com/login.php"]];
NSLog(@"%d", all.count);
for (NSHTTPCookie *cookie in all)
NSLog(@"Name: %@ : Value: %@", cookie.name, cookie.value);
NSLog(@"Comment: %@ : CommentURL: %@", cookie.comment, cookie.commentURL);
NSLog(@"Domain: %@ : ExpiresDate: %@", cookie.domain, cookie.expiresDate);
NSLog(@"isHTTPOnly: %c : isSecure: %c", cookie.isHTTPOnly, cookie.isSecure);
NSLog(@"isSessionOnly: %c : path: %@", cookie.isSessionOnly, cookie.path);
NSLog(@"portList: %@ : properties: %@", cookie.portList, cookie.properties);
NSLog(@"version: %u", cookie.version);
我也找到了这段代码来使用这些 cookie,但我不知道如何使用它:
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookies];
这是我的 POST 方法,我使用的是 RestKit API:
- (IBAction)addLinkPressed:(UIButton *)sender
[RKClient clientWithBaseURLString:@"http://MyWebsite.com"];
NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
self.linkField.text, @"url",
self.linkTitleField.text, @"title",
self.linkSummaryField.text, @"summary",
nil];
RKRequest *request = [[RKClient sharedClient] post:@"/send_link.php" params:params delegate:self];
[request setUserData:@"sendLink"];
问题:我应该存储 cookie 的哪个属性以将其用于登录信息,我应该将它放在我的代码中的什么位置?
【问题讨论】:
所以还没有解决方案? @FadyKamal 我发布了我的方法,希望对您有所帮助。 【参考方案1】:我通过一些低效的方式解决了这个问题。这是我的方法: 首先,我尝试发布到 Web 服务,发布后我解析返回的 html 以查看发布是否成功。如果发布成功,我会向用户发送一条适当的消息,表明您发布成功,但如果不成功,可能有两个原因:第一:发布执行期间出现错误第二:用户未登录。我认识到第一个错误和第二个错误之间的区别只是解析响应 HTML。 这是我用于此方法的代码(这是用户想要更改密码的时间)
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error
NSRange range = [[error localizedDescription] rangeOfString:@"-1012"];
if (range.length > 0)
//First error occurs here
RKLogError(@"Hit error: %@", error);
- (IBAction)requestToChangePasswordPressed
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Loading";
[RKClient clientWithBaseURLString:@"http://WebServiceDomain.com"];
NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
self.oldPasswordField.text, @"oldPassword",
self.passwordNew.text, @"newPassword",
self.confirmPasswordField.text, @"confirmPassword",
nil];
RKRequest *request = [[RKClient sharedClient] post:@"/change_password.php" params:params delegate:self];
[request setUserData:@"changePassword"];
[self.view endEditing:YES];
[MBProgressHUD hideHUDForView:self.view animated:YES];
- (void)autoLogin
[RKClient clientWithBaseURLString:@"http://WebServiceDomain.com"];
[RKObjectManager sharedManager].client=[RKClient sharedClient];
RKParams *parameters = [RKParams params];
[parameters setValue:[[NSUserDefaults standardUserDefaults] objectForKey:@"defaultUsername"] forParam:@"username"];
[parameters setValue:[[NSUserDefaults standardUserDefaults] objectForKey:@"defaultPassword"] forParam:@"password"];
[[RKClient sharedClient] setAuthenticationType:RKRequestAuthenticationTypeHTTP];
// because we have two POSTs and we want to use the same method for both of the for didLoadResponse: we set the UserDate like bellow
RKRequest *request = [[RKClient sharedClient] post:@"/login.php" params:parameters delegate:self];
[request setUserData:@"login"];
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Loading";
id userData = [request userData];
if ([userData isEqual:@"login"])
if ([request isGET])
// Handling GET /foo.xml
if ([response isOK])
// Success! Let's take a look at the data
NSLog(@"Retrieved XML: %@", [response bodyAsString]);
else if ([request isPOST])
// Handling POST /other.json
if ([response isJSON])
NSLog(@"Got a JSON response back from our POST!");
else if ([request isDELETE])
// Handling DELETE /missing_resource.txt
if ([response isNotFound])
NSLog(@"The resource path '%@' was not found.", [request resourcePath]);
else if ([userData isEqual:@"sendLink"])
NSData *addLinksHtmlData = response.body;
// 2
TFHpple *addlinksParser = [TFHpple hppleWithHTMLData:addLinksHtmlData];
// 3
NSString *errorLinksXpathQueryString = @"//div[@class='errorBox']/ul/li";
NSArray *errorLinksNodes = [addlinksParser searchWithXPathQuery:errorLinksXpathQueryString];
// 4
NSMutableArray *newErrorLinks = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in errorLinksNodes)
// 5
AllModels *errorTitle = [[AllModels alloc] init];
[newErrorLinks addObject:errorTitle];
// 6
errorTitle.errorTitle = [[element firstChild] content];
// 8
self.linkErrorObjects = newErrorLinks;
NSString *successLinksXpathQueryString = @"//div[@class='successBox']";
NSArray *successLinksNodes = [addlinksParser searchWithXPathQuery:successLinksXpathQueryString];
// 4
NSMutableArray *newSuccessLinks = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in successLinksNodes)
// 5
AllModels *successTitle = [[AllModels alloc] init];
[newSuccessLinks addObject:successTitle];
// 6
successTitle.successTitle = [[element firstChild] content];
// 8
self.linkSuccessObjects = newSuccessLinks;
else
NSLog(@"HTTP status code: %d", response.statusCode);
NSLog(@"HTTP status message: %@", [response localizedStatusCodeString]);
NSLog(@"Header fields: %@", response.allHeaderFields);
NSLog(@"Body: %@", response.bodyAsString);
NSData *HtmlData = response.body;
// 2
TFHpple *addParser = [TFHpple hppleWithHTMLData:HtmlData];
// 3
NSString *errorXpathQueryString = @"//div[@class='errorBox']/ul/li";
NSArray *errorNodes = [addParser searchWithXPathQuery:errorXpathQueryString];
// 4
NSMutableArray *newError = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in errorNodes)
// 5
AllModels *errorTitle = [[AllModels alloc] init];
[newError addObject:errorTitle];
// 6
errorTitle.errorTitle = [[element firstChild] content];
// 8
self.ErrorObjects = newError;
NSString *successXpathQueryString = @"//div[@class='successBox']";
NSArray *successNodes = [addParser searchWithXPathQuery:successXpathQueryString];
// 4
NSMutableArray *newSuccess = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in successNodes)
// 5
AllModels *successTitle = [[AllModels alloc] init];
[newSuccess addObject:successTitle];
// 6
successTitle.successTitle = [[element firstChild] content];
// 8
self.successObjects = newSuccess;
[self errorCheck];
[MBProgressHUD hideHUDForView:self.view animated:YES];
[MBProgressHUD hideHUDForView:self.view animated:YES];
- (void)errorCheck
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Loading";
if(self.errorObjects.count > 0)
AllModels *errorlink = [self.errorObjects objectAtIndex:0];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"There is a problem" message:errorlink.errorTitle delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil , nil];
[alert show];
else
if(self.linkErrorObjects.count > 0)
[self autoLogin];
[self requestToChangePasswordPressed];
else
AllModels *successlink = [self.successObjects objectAtIndex:0];
self.successLabel.hidden = NO;
self.successLabel.text = successlink.successTitle;
NSLog(@"Success Title: %@",successlink.successTitle);
[UIView animateWithDuration:3.0
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^ self.successLabel.alpha = 0.0;
completion:^(BOOL fin) if (fin) [self.successLabel removeFromSuperview]; ];
[self performSelector:@selector(dismissModalViewController) withObject:nil afterDelay:1.0];
[MBProgressHUD hideHUDForView:self.view animated:YES];
[MBProgressHUD hideHUDForView:self.view animated:YES];
【讨论】:
以上是关于如何获取 cookie 并将它们用于其他请求,如 POST ( iOS )?的主要内容,如果未能解决你的问题,请参考以下文章
如何从HTTP请求将图像加载到UIButton Swift中
从 OWIN Cookie 获取不记名令牌并将其放在 API 请求中