AFNetworking 2.0将标头添加到GET请求


78

我刚刚开始使用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标头。

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



3
@RyanR不是重复的。那是来自AFN 1.x而不是2.0。从那时起,一切都彻底改变了。
Mackey18年

根据迁移指南, AFHttpClient仍然存在,并仍然负责为您的应用执行Http请求
RyanR 2013年

2
一个文档冲突的开源项目?NEVAR。AFHTTPClient-> AFHTTPSessionManager显然是。您说得对,使用setDefaultHeader糟透了。在30秒钟的文档搜索中,我发现AFHTTPRequestSerializer会根据每个请求负责HTTPHeader。
RyanR 2013年

2
@RyanR D'oh错过了!由于您的发现,找到了正确的方法:manager.requestSerializer setValue:<#(NSString *)#> forHTTPHeaderField:<#(NSString *)#>
Mackey18

Answers:


84

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];
}

4
您介意添加此功能的摘要吗?我是一个尝试学习ios的android家伙,我不太确定如何使用此答案。
ChuckKelly 2013年

1
但是为什么在序列化程序中设置标头???我还注意到,这种方式是持久的,因此一旦设置了标头字段,它就会永远存在!(我必须添加自己的方法来删除它们)
Peter Lapisu 2014年

4
@PeterLapisu使用nilfor调用此方法value将删除它。您不应该使用标头将临时值从客户端传递到服务器-这是您的有效负载的一部分。标头用于不经常更改的值,例如auth数据,缓存控制等。某些服务器甚至会根据匹配的标头参数确定是否返回缓存的数据,您不会意外地避免这种情况。如果您只需要为单个请求设置标头,则我怀疑这是属于有效负载的数据。
RyanR 2014年

2
@PeterLapisu我不知道AFN团队的推理是什么,但是从设计的角度来看绝对有道理。串行器是知道如何对所使用的任何协议的请求和响应进行编码/解码的东西。如果是通过FTP,则序列化该信息的方式将不同于通过消息队列进行序列化。这样,只有负责该类型传输的组件才知道传输的详细信息(这是[encapsulation](en.wikipedia.org/wiki/…的一部分
RyanR 2014年

2
仍然认为它是一个糟糕的设计问题github.com/AFNetworking/AFNetworking/issues/1793
Peter Lapisu 2014年

146

这是使用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"];

1
谢谢你的例子!
diegomen,2014年

17

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

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

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

7

我已经使用此表格预约了特定的标题。

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]);

               }
 ];

您是否不认为,自设置它们的那一刻起,这些标头就会与任何请求一起发送?
vahotm '16

6

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

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.HTTPAdditionalHeaders = @{@"Accepts": @"application/json"};

mySingletonSessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:kMyBaseUrl] sessionConfiguration:config];


-3

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

[[FRHTTPReqManager sharedManager].requestSerializer setValue:value forHTTPHeaderField:key];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.