【问题标题】:Get cookies from NSHTTPURLResponse从 NSHTTPURLResponse 获取 cookie
【发布时间】:2013-10-04 16:25:51
【问题描述】:

我有一个非常奇怪的问题,我正在请求一个 URL,我想从中获取 cookie,我使用这种方式获取 cookie:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
    NSDictionary *fields = [HTTPResponse allHeaderFields];
    NSString *cookie = [fields valueForKey:"Set-Cookie"];
}

但是 cookie 不完整,缺少某些字段,我在 PostMan 上检查过,所有 cookie 都在那里。

我在启动NSURLRequest时也使用了这种方法。

[request setHTTPShouldHandleCookies:YES];

问题出在哪里?

注意:这个问题在 iOS 上,我有一个 android 版本,它工作正常,所有的 cookie 都在那里。

【问题讨论】:

  • 获取 Charles Proxy(免费一个月)并查看服务器发送的确切内容。
  • @Zaph 我已经在android应用程序上测试了服务器,所有的cookies都出现了,但是在iOS中,有一些cookies丢失了。
  • NSHTTPCookieStorage 是一个可能的解决方案。但是,除了查看服务器发送的确切内容之外,没有其他替代方法。也许服务器正在键入用户代理并发送不同的 cookie 或其他东西。 Charles 易于使用,甚至可以使用 SSL。
  • @Zaph 我已经在 Charles Proxy 上测试了该服务,请求包含我应该获得的所有 cookie。
  • 我遇到了同样的问题,@vn_serg 给出的解决方案效果很好

标签: objective-c cookies nsurlrequest nshttpurlresponse


【解决方案1】:

它会起作用的。

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
        NSString *cookieValue = @"";
        NSString *cookieHeaderValue = @"";
        NSString *finalCookieValue = @"";
        
        for (NSHTTPCookie *each in cookieStorage.cookies) {
            if ([each.name isEqualToString:@"ASP.NET_SessionId"]) {
                cookieHeaderValue = [cookieHeaderValue stringByAppendingString:each.name];
                cookieHeaderValue = [cookieHeaderValue stringByAppendingString:@"="];
                cookieHeaderValue = [cookieHeaderValue stringByAppendingString:each.value];
                cookieHeaderValue = [cookieHeaderValue stringByAppendingString:@";"];
            } else {
                cookieValue = [cookieValue stringByAppendingString:each.name];
                cookieValue = [cookieValue stringByAppendingString:@"="];
                cookieValue = [cookieValue stringByAppendingString:each.value];
                cookieValue = [cookieValue stringByAppendingString:@";"];
            }
        }
        
        finalCookieValue = [NSString stringWithFormat:@"%@%@", cookieHeaderValue, cookieValue];

【讨论】:

    【解决方案2】:
    for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies])
    {
        NSLog(@"name: '%@'\n",   [cookie name]);
        NSLog(@"value: '%@'\n",  [cookie value]);
        NSLog(@"domain: '%@'\n", [cookie domain]);
        NSLog(@"path: '%@'\n",   [cookie path]);
    }
    

    第二个代码是:

    NSHTTPURLResponse *HTTPResponsesss = (NSHTTPURLResponse *)response;
    NSDictionary *fields = [HTTPResponsesss allHeaderFields];
    NSString *cookie = [fields valueForKey:@"Set-Cookie"]; // It is your cookie
    

    NSLog(@"%@", cookie);

    两个代码都可以正常工作。

    【讨论】:

      【解决方案3】:

      @biloshkurskyi.ss 答案是正确的。

      我花了半天时间试图找出为什么我的一些 cookie 没有出现在 iOS 上的 response.allHeaderFields 中,但在 Android 上却出现了(使用相同的服务)。

      原因是因为一些cookie被提前提取并存储在共享cookie存储中。它们不会出现在 allHeaderFields 中。

      如果有人需要,这是答案的 swift 3 版本:

      let request = URLRequest(url: myWebServiceUrl)
      let session = URLSession.shared
      let task = session.dataTask(with: request, completionHandler: {
          (data, response, error) in
          if let error = error {
              print("ERROR: \(error)")
          } else {
              print("RESPONSE: \(response)")
              if let data = data, let dataString = String(data: data, encoding: .utf8) {
                  print("DATA: " + dataString)
              }
              for cookie in HTTPCookieStorage.shared.cookies! {
                  print("EXTRACTED COOKIE: \(cookie)") //find your cookie here instead of httpUrlResponse.allHeaderFields
              }
          }
      })
      task.resume()
      

      【讨论】:

      • 你是救生员!有很多关于这个的问题的答案是错误的(使用 cookiesWithResponseHeaderFields),而你有一个正确的答案。我花了无数个小时试图弄清楚这一点。谢谢。
      【解决方案4】:

      试试这个代码:

      for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies])
      {
          NSLog(@"name: '%@'\n",   [cookie name]);
          NSLog(@"value: '%@'\n",  [cookie value]);
          NSLog(@"domain: '%@'\n", [cookie domain]);
          NSLog(@"path: '%@'\n",   [cookie path]);
      }
      

      【讨论】:

      • 请注意,当应用启用沙盒时,这在 OSX 上不起作用
      【解决方案5】:

      您是否尝试过以下代码示例,它应该可以工作:

      - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
      {
          NSArray *cookies =[[NSArray alloc]init]; 
          cookies = [NSHTTPCookie 
              cookiesWithResponseHeaderFields:[response allHeaderFields] 
              forURL:[NSURL URLWithString:@""]]; // send to URL, return NSArray
      }
      

      【讨论】:

      • 同理,“Set-Cookie”并不包含所有的cookies。
      • 如果服务器不发送 cookie,客户端就不能拥有 cookie。
      • @ipmcc 它确实发送了cookie,但不是iOS的所有cookie,当在android上使用相同的服务时,它会返回所有cookie。
      • 那听起来你的服务器端有问题。
      • 这很有用!由于从“allHeaderFields”中手动拉出“Set-Cookie”会导致严重的未转义 cookie(这变得非常难以解析)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 2013-04-29
      • 2021-04-06
      • 1970-01-01
      相关资源
      最近更新 更多