【问题标题】:AFNetworking 2.0 add headers to GET requestAFNetworking 2.0 向 GET 请求添加标头
【发布时间】:2013-10-28 06:41:32
【问题描述】:

我刚刚开始使用 AFNetworking 2.0,我想知道如何将标头放入 HTTP Get 请求中。文档设置了这样的 GET:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"foo": @"bar"};
[manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];

但由于我们不处理 NSURLRequests,我不确定如何设置 HTTP 标头。

任何帮助将不胜感激。
问候,
迈克

【问题讨论】:

  • @RyanR 不是重复的。那是来自 AFN 1.x 而不是 2.0。从那以后,一切都完全改变了。
  • 根据migration guide AFHttpClient 仍然存在并且仍然负责为您的应用执行Http请求
  • 一个文档冲突的开源项目?内瓦尔。 AFHTTPClient -> AFHTTPSessionManager 显然。你是对的,使用setDefaultHeader 很糟糕。对文档进行 30 秒搜索,我发现 AFHTTPRequestSerializer 负责按请求处理 HTTPHeaders。
  • @RyanR D'oh 错过了!感谢您的发现,找到了正确的方法:manager.requestSerializer setValue:<#(NSString *)#> forHTTPHeaderField:<#(NSString *)#>

标签: iphone ios objective-c afnetworking afnetworking-2


【解决方案1】:

这是一个使用 AFNetworking 2.0 的示例

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:@"calvinAndHobbesRock" forHTTPHeaderField:@"X-I do what I want"];

[manager GET:@"http://localhost:3000" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

关键是以下两行:

manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:@"calvinAndHobbessRock" forHTTPHeaderField:@"X-I-do-what-I-want"];

【讨论】:

  • 谢谢你的例子!!
【解决方案2】:

AFNetworking 2.0 的精彩文档使这有点难找,但它就在那里。在AFHTTPRequestSerializer 上是-setValue:forHTTPHeaderField:

或者,如果您按照他们推荐的方法创建从AFHTTPSessionManager 派生的会话管理器,那么该类可以覆盖一个方法来修改每个请求-dataTaskWithRequest:completionHandler: 的标头。我使用它来检查请求并根据具体情况修改标头,并且更喜欢它而不是修改序列化程序,因为它保留了该管理器中包含的网络责任(并避免与单例混淆)

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse *, id, NSError *))completionHandler
{
    static NSString *deviceId;
    if(!deviceId)
    {
        deviceId = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    }

    NSMutableURLRequest *req = (NSMutableURLRequest *)request;
    // Give each request a unique ID for tracing
    NSString *reqId = [NSString stringWithFormat:@"%@+%@", deviceId, [[NSUUID UUID] UUIDString] ];
    [req setValue:reqId forHTTPHeaderField:"x-myapp-requestId"];
    return [super dataTaskWithRequest:req completionHandler:completionHandler];
}

【讨论】:

  • 您介意添加一个关于如何使用它的 sn-p 吗?我是一个试图学习 ios 的 android 人,但我不太确定如何使用这个答案。
  • 但是为什么在序列化器中设置了标头???我还注意到这种方式它们是持久的,所以一旦你设置了一个标题字段,它就会永远留在那里! (我必须添加自己的方法来删除它们)
  • @PeterLapisu 用nilvalue 调用此方法将删除它。您不应该使用标头将临时值从客户端传递到服务器 - 这是您的有效负载的一部分。 headers 用于不经常更改的值,例如 auth 数据、缓存控制等。有些服务器甚至会根据 header 参数匹配来确定是否返回缓存数据,这是您不想意外阻止的。如果您只需要为单个请求设置标头,我怀疑它是属于有效负载的数据。
  • @PeterLapisu 我不知道 AFN 团队的推理是什么,但从设计的角度来看这绝对是有道理的。序列化器知道如何对您使用的任何协议的请求和响应进行编码/解码。如果它是通过 FTP,那么您会以不同于通过消息队列的方式序列化该信息。这样,只有负责该类型传输的组件才知道传输的详细信息(这是[封装]的一部分(en.wikipedia.org/wiki/…
  • 仍然认为这是一个糟糕的设计问题github.com/AFNetworking/AFNetworking/issues/1793
【解决方案3】:

添加响应和请求序列化程序解决了我的问题。

manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];

[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

【讨论】:

    【解决方案4】:

    我已使用此表单与特定标题进行约会。

    AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
    [operationManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [operationManager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    
    [operationManager POST:url
                parameters:params
                   success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
                       if (success) {
                           success(responseObject);
                       }
    
                   }
                   failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    
                       NSLog(@"Error: %@", [error description]);
    
                   }
     ];
    

    【讨论】:

    • 您不认为,从您设置它们的那一刻起,这些标头将与任何请求一起发送吗?
    【解决方案5】:

    这是我认为最好的选择。在某处的单例中,使用NSURLSessionConfiguration 配置AFHTTPSessionManager,然后在每次要发出请求时使用AFHTTPSessionManager

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.HTTPAdditionalHeaders = @{@"Accepts": @"application/json"};
    
    mySingletonSessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:kMyBaseUrl] sessionConfiguration:config];
    

    【讨论】:

      【解决方案6】:

      我这样做了......对于那些传递令牌的人

      [manager.requestSerializer setValue:[NSString stringWithFormat:@"Token token=\"%@\"", _userObj.oAuth] forHTTPHeaderField:@"Authorization"];
      

      【讨论】:

        【解决方案7】:

        使用以下代码放置任何类型的标头值:

        [[FRHTTPReqManager sharedManager].requestSerializer setValue:value forHTTPHeaderField:key];
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-24
          • 1970-01-01
          • 2015-03-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多