htttp网络请求cookie的读取与写入(NSHTTPCookieStorage)

 

一.Cookie

Cookie是在客户端存储服务器状态的一种机制,Web服务器可以通过Set-Cookie或者Set-Cookie2 HTTP头部设置Cookie。

Cookie可以分为两类,会话Cookie和持久Cookie,会话Cookie是临时Cookie,当前会话结束(浏览器退出)时Cookie会被删除。持久Cookie会存储在用户的硬盘上,浏览器退出,然后重新启动后Cookie仍然存在。会话Cookie和持久Cookie的区别在于过期时间,如果设置了Discard参数(Cookie 版本1)或者没有设置Expires(Cookie版本0)或Max-Age(Cookie版本1)设置过期时间,则此Cookie为会话Cookie

Cookie有两个版本,一个是版本0(Netscape Cookies)和版本1(RFC 2965),目前大多数服务器使用的Cookie 0。

二.NSHTTPCookie

在iOS中使用NSHTTPCookie类封装一条cookie,通过NSHTTPCookie的方法读取到cookie的通用属性。

可以通过手工赋值的方式创建Cookie,如
+ (id)cookieWithProperties:(NSDictionary *)properties;
- (id)initWithProperties:(NSDictionary *)properties;
也可以从Cookie中读取到所有属性。
- (NSDictionary *)properties;

使用NSHTTPCookie的类方法可以将NSHTTPCookie实例与HTTP cookie header相互转换.
根据NSHTTPCookie实例数组生成对应的HTTP cookie header
+ (NSDictionary *)requestHeaderFieldsWithCookies:(NSArray *)cookies;

从headerFileds中读取到Cookie相关内容,生成NSHTTPCookie实例对象数组。
+ (NSArray *)cookiesWithResponseHeaderFields:(NSDictionary *)headerFields forURL:(NSURL *)theURL;
该方法会忽略headerFileds中与cookie无关的字段,如果headerFileds中的cookie没有指定domain,则使用theURL的domain,如果没有指定path,则使用”/”.

除非NSURLRequest明确指定不使用cookie(HTTPShouldHandleCookies设为NO),否则URL loading system会自动为NSURLRequest发送合适的存储cookie。从NSURLResponse返回的cookie也会根据当前的cookie访问策略(cookie acceptance policy)接收到系统中。

应用如下

1.原生NSURLConnection写法

一.获取cookie
- (IBAction)cookieTouched:(id)sender {
    NSURL *url = [NSURL URLWithString:@"http://xxx.xxx"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url]
                                             cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                         timeoutInterval:3];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:queue
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
                              
                               //转换NSURLResponse成为HTTPResponse
                               NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
                               //获取headerfields
                               NSDictionary *fields = [HTTPResponse allHeaderFields];//原生NSURLConnection写法
                               // NSDictionary *fields = [operation.response allHeaderFields]; //afnetworking写法
                               NSLog(@"fields = %@",[fields description]);
 
                               //获取cookie方法1
                               // NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:fields forURL:url];
							   //获取cookie方法2
                               //NSString *cookieString = [[HTTPResponse allHeaderFields] valueForKey:@"Set-Cookie"];
                               //获取cookie方法3
                               NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
                               for (NSHTTPCookie *cookie in [cookieJar cookies]) {
                                   NSLog(@"cookie%@", cookie);
                               }
                           }];
    
}

2.AFNetworking 写法

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFCompoundResponseSerializer serializer];
    //demo中的api返回的是html数据,不是json
    [manager POST:@"http://xxx.xxx" parameters:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"\n======================================\n");
        NSDictionary *fields = ((NSHTTPURLResponse*)task.response).allHeaderFields;
        NSLog(@"fields = %@",[fields description]);
        NSURL *url = [NSURL URLWithString:@"http://xxx.xxx"];
        NSLog(@"\n======================================\n");
        //获取cookie方法1
        NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:fields forURL:url];
        for (NSHTTPCookie *cookie in cookies) {
            NSLog(@"cookie,name:= %@,valuie = %@",cookie.name,cookie.value);
        }
        NSLog(@"\n======================================\n");
//        //获取cookie方法2
//        NSString *cookies2 = [((NSHTTPURLResponse*)task.response) valueForKey:@"Set-Cookie"];
//        NSLog(@"cookies2 = %@",[cookies2 description]);
 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
    }];

3.清空Cookie

NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
  NSArray *cookieArray = [NSArray arrayWithArray:[cookieJar cookies]];
  for (NSHTTPCookie *obj in cookieArray) {
    [cookieJar deleteCookie:obj];
  }

4.手动设置Cookie 手动设置的Cookie不会自动持久化到沙盒

//第一次请求手动设置个cookie
-(void)test1:(NSString*)urlString{
    NSURL *url = [NSURL URLWithString:@"http://xxx.xxx"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:@"username" forKey:NSHTTPCookieName];
    [cookieProperties setObject:@"my ios cookie" forKey:NSHTTPCookieValue];
    [cookieProperties setObject:@"dev.skyfox.org" forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:@"dev.skyfox.org" forKey:NSHTTPCookieOriginURL];
    [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
    [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
    [cookieProperties setObject:[NSDate dateWithTimeIntervalSinceNow:60*60] forKey:NSHTTPCookieExpires];//设置失效时间
    [cookieProperties setObject:@"0" forKey:NSHTTPCookieDiscard]; //设置sessionOnly
 
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
    [self.myWebView loadRequest:request];
}
//第二次请求会自动带上Cookie
- (IBAction)test2:(id)sender {
    NSURL *url = [NSURL URLWithString:@"http://xxx.xxx"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [self.mywebview2 loadRequest:request];
}

//设置多个Cookie
NSArray * heardCookie = [NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary
dictionaryWithObject:[[NSString alloc] 
initWithFormat:@"cookieName=%@", userstring] //这里的cookieName要后台给
forKey:@"Set-Cookie"] 
forURL:[NSURL URLWithString:@"http://"]];

[[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookies:heardCookie forURL:[NSURL URLWithString:@"http://"] mainDocumentURL:nil];

//passwd
NSArray * heardCookie = [NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary 
dictionaryWithObject:[[NSString alloc] 
initWithFormat:@"cookiePasswd =%@", passString] //cookiePasswd也是后台给
forKey:@"Set-Cookie"] 
forURL:[NSURL URLWithString:@"http://"]];

[[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookies:heardCookie forURL:[NSURL URLWithString:@"http://"] mainDocumentURL:nil];

//另一种设置Cookie的方法
NSString* cookie = [[NSString alloc] initWithFormat:@"accessToken=%@;path=/;domain=%@;httponly", token, host];
NSArray *headeringCookie = [NSHTTPCookie
                                cookiesWithResponseHeaderFields:
                                @{
                                  @"Set-Cookie":cookie,
                                  }
                                forURL:[NSURL URLWithString:url]];
// 通过setCookies方法,完成设置,这样只要一访问URL为HOST的网页时,会自动附带上设置好的header
 [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:headeringCookie forURL:[NSURL URLWithString:url]
mainDocumentURL:nil];

通过NSHTTPCookieStorage可读取/修改cookie接收策略,默认为NSHTTPCookieAcceptPolicyAlways.

- (NSHTTPCookieAcceptPolicy)cookieAcceptPolicy;
- (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)aPolicy.

一共有三种cookie accept policy,

typedef enum {
   NSHTTPCookieAcceptPolicyAlways,
   NSHTTPCookieAcceptPolicyNever,
   NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
} NSHTTPCookieAcceptPolicy;
NSHTTPCookieAcceptPolicyAlways:接收所有cookie,默认策略.
NSHTTPCookieAcceptPolicyNever: 拒绝所有cookie
NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只接收main document domain中的cookie.

三.相关通知

NSHTTPCookieManagerCookiesChangedNotification
当NSHTTPCookieStorage实例中的cookies变化时发出此通知。

NSHTTPCookieManagerAcceptPolicyChangedNotification
当NSHTTPCookieStorage实例的cookie acceptance policy变化时发出此通知。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java实现异步批量发送HTTP请求数据至服务端可以采用Java的异步框架,如Spring Boot中的异步机制来实现。 具体实现步骤如下: 1. 引入相关依赖:在pom.xml文件中添加Spring Boot的异步依赖,如下所示: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-async</artifactId> </dependency> ``` 2. 创建异步任务:使用@Async注解创建异步任务,如下所示: ``` @Service public class AsyncService { @Async public CompletableFuture<String> sendHttpRequest(String url, String data) throws Exception { // 创建HttpClient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建HttpPost对象 HttpPost httpPost = new HttpPost(url); // 设置请求httpPost.setHeader("Content-Type", "application/json"); // 设置请求体 StringEntity entity = new StringEntity(data, "utf-8"); httpPost.setEntity(entity); // 发送请求 CloseableHttpResponse response = httpClient.execute(httpPost); // 处理响应结果 String result = EntityUtils.toString(response.getEntity(), "utf-8"); // 关闭资源 response.close(); httpClient.close(); return CompletableFuture.completedFuture(result); } } ``` 在上述代码中,我们使用@Async注解创建了一个异步任务sendHttpRequest(),该方法用于发送HTTP请求并返回响应结果。 3. 调用异步任务:在需要异步发送HTTP请求的地方,调用异步任务即可,如下所示: ``` @Autowired private AsyncService asyncService; public void sendHttpRequests() throws Exception { List<String> urls = Arrays.asList("http://example.com/api/1", "http://example.com/api/2", "http://example.com/api/3"); List<String> data = Arrays.asList("{\"name\":\"张三\"}", "{\"name\":\"李四\"}", "{\"name\":\"王五\"}"); List<CompletableFuture<String>> futures = new ArrayList<>(); for (int i = 0; i < urls.size(); i++) { CompletableFuture<String> future = asyncService.sendHttpRequest(urls.get(i), data.get(i)); futures.add(future); } CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).join(); List<String> results = futures.stream().map(CompletableFuture::join).collect(Collectors.toList()); // 处理响应结果 // ... } ``` 在上述代码中,我们创建了一个List<CompletableFuture<String>>类型的futures,用于存储异步任务的返回结果。然后,我们循环遍历urls和data,调用异步任务sendHttpRequest()并将返回结果添加到futures列表中。接着,我们使用CompletableFuture.allOf()方法等待所有异步任务执行完毕,然后将所有异步任务的返回结果存储在results列表中,最后对响应结果进行处理。 通过以上步骤,我们就可以实现异步批量发送HTTP请求数据至服务端。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值