如何使用 AFNetworking-2.0 执行 JSON 编码的 GET 请求?

Posted

技术标签:

【中文标题】如何使用 AFNetworking-2.0 执行 JSON 编码的 GET 请求?【英文标题】:How to do a JSON encoded GET request with AFNetworking-2.0? 【发布时间】:2013-12-10 18:31:21 【问题描述】:

我正在尝试使用类似于 to this post which describes doing a PUT/POST for RESTful API 的模式,但用于 GET。

我的原始代码看起来几乎相同,除了我使用了GET: 关键字。我很快发现,它不是发送 JSON 正文,而是对参数进行 url 编码。 AFJSONSerializer 类的文档中没有提到这一点。您必须访问超类文档 (AFHTTPSerializer) 并阅读其属性,您将在其中找到 the one about HTTPMethodsEncodingParametersInURI。默认情况下,该集合由 HEAD、GET 和 DELETE 填充。那么对于这些​​类型的请求,JSON 序列化器显然会恢复到其父类的行为?

所以我整理了以下代码:

AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
manager.securityPolicy.allowInvalidCertificates = YES;
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.requestSerializer.HTTPMethodsEncodingParametersInURI = [NSSet set];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername: currentUser() password: currentPassword()];
[manager
    GET: @"https://172.16.214.214:44321/trees"
    parameters: [NSDictionary dictionary]
    success:^(NSURLSessionDataTask* task, id responseObject)
        NSLog(@"Response: %@", responseObject);
    failure:^(NSURLSessionDataTask* task, NSError* error)
        NSLog(@"Error: %@", error);];

设置HTTPMethodsEncodingParametersInURI = [NSSet set] 的行旨在让我获得JSON 编码参数,就像我想要的GET 一样。不幸的是,当我使用它并在我的错误控制台中得到以下信息时,我在服务器上什么也看不到:

2013-12-10 10:11:14.149 myValve[957:60b] Error: Error Domain=NSURLErrorDomain Code=-1005 "The
network connection was lost." UserInfo=0x17e5d4b0
NSErrorFailingURLStringKey=https://172.16.214.214:44321/trees,
NSErrorFailingURLKey=https://172.16.214.214:44321/trees, NSLocalizedDescription=The network
connection was lost., NSUnderlyingError=0x17e53240 "The network connection was lost."

我还缺少什么?

【问题讨论】:

我希望这实际上是一个答案@Rob。该链接有助于明确为什么框架可能不支持它。谢谢。 我已将其发布为答案。我只是不想让别人的出色答案看起来像我受到赞扬。同样,我总是不愿发布可以被解读为“不要这样做”的答案。大声笑。 【参考方案1】:

此处 AFNetworking 行为背后的基本原理可能在 Stack Overflow 问题HTTP GET with request body 中得到了最简洁的解释。其中一个答案quotes Ray Fielding:

... 换句话说,任何 HTTP 请求消息都被允许包含消息体,因此必须考虑到这一点来解析消息。但是,GET 的服务器语义受到限制,因此主体(如果有)对请求没有语义意义。解析的要求与方法语义的要求是分开的。

所以,是的,您可以使用 GET 发送正文,但不,这样做从来没有用处。

HTTP/1.1 spec 将GET 定义为“检索由 Request-URI 标识的任何信息(以实体的形式)”,并且不考虑将信息包含在请求正文中。所以在GET请求中使用body在技术上可能不会被禁止,但充其量是非标准的。 AFNetworking 选择不支持它并不完全令人惊讶。

因此,对于 GET 请求,您可能不希望将 JSON 放入正文中。通常会将参数添加到 URL。如果您想在请求正文中发送 JSON,请执行 POST

【讨论】:

【参考方案2】:

好像连接不上服务器,有没有尝试在ios外拨打电话?

作为参考,我通常会发出这样的 JSON 请求:

NSURL *url = @"https://172.16.214.214:44321/trees";
NSData* data = [NSData dataWithContentsOfURL: url];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

【讨论】:

以上是关于如何使用 AFNetworking-2.0 执行 JSON 编码的 GET 请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AFNetworking 2.0 处理 Parse.com Rest API 错误

如何在旧的 AFNetworking 中使用 AFNetworking 2.0+?

AFNetworking 2.0 和单元测试

通过 Afnetworking 2.0 从 URL 获取一半大小的 UIImage

AFNetworking 2.0。如何检查套接字的可达性状态(managerForAddress :)?

AFNetworking 2.0 中的 AFHTTPRequestOperationManager 如何传递 HTTPBody 标签