带参数的NSMutableURLRequest - 无法解析响应

时间:2014-10-29 20:46:38

标签: ios objective-c json xcode nsmutableurlrequest

我正在尝试创建一个URL的连接,该URL打印出JSON代码,然后对其进行解析和处理。我的网址有一个名为bypass的参数。 URL如下所示:

http://www.getchanged.net/json.asp?bypass=MIGCBgkrBgEEAYI3WAOxxx

我无法解决此问题,因为它总是说Connection failed with error: cannot parse response

NSURL *aUrl = [NSURL URLWithString:@"http://www.getchanged.net/json.asp"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

[request setHTTPMethod:@"GET"];
NSString *postString = @"bypass=MIGCBgkrBgEEAYI3WAOxxx";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

错误:

2014-10-29 21:43:39.529 TestMap[57987:1931535] Connection failed with error: cannot parse response

这里有什么问题?

请注意: 我稍微更换了旁路哈希,因为它包含合理的数据。该网站正常运行并打印出JSON输出。

5 个答案:

答案 0 :(得分:4)

有几点意见:

  1. 关键问题是您发出了GET请求,但在请求正文中提供了bypass参数。对于POST个请求,应将参数添加到正文中,但对于GET个请求,应将其添加到网址中。

  2. 如果此bypass键可能包含保留字符(例如空格,&+等),则您希望百分比转义您为bypass提供的价值。如果你保证它只是字母数字,你就可以逃脱而不会逃避它,但作为一般规则,你应该总是百分之百地逃避HTTP参数。

  3. 虽然第1点可能会解决此问题,但有时Web服务会期望设置某些标头字段。例如,通常会设置请求的Content-Type标头(例如,看起来请求的Content-Type应为application/x-www-form-urlencoded)。

  4. 您说您收到错误消息,"连接失败并显示错误:无法解析响应"。您还没有向我们展示产生此错误的代码,但我认为这是在您的代码尝试将响应解析为JSON时生成的。

    将来,在诊断这些问题时,我发现实际检查响应的详细信息很有用。值得注意的是,响应的标题将包含在NSURLResponse中(实际上是NSHTTPURLResponse,其statusCode数值非常明显。响应的主体通常是错误的字符串表示(通常当Web服务失败时,它会生成错误的文本或HTML描述)。

    每当您将来遇到这样的错误时,请始终查看statusCode以及服务器返回的文本,因为这有助于您诊断正在进行的操作。它将比通用的更具信息性#34;我无法解析响应"消息。

  5. 如果您的网络界面有效,而且应用程序界面不起作用,那么使用像Charles这样的工具观察由此产生的请求有时会很有用。 Web浏览器并将其与应用程序生成的请求进行比较。在诊断这些问题时,这非常有用。

    此外,如果您使用像Charles这样的东西,这允许您手动检查服务器的状态代码和文本响应,我建议您可以在#4点以编程方式处理。

答案 1 :(得分:2)

将请求HTTPMethod更改为POST,您可以。

@property(copy)NSData * HTTPBody;

@discussion This data is sent as the message body of the request, as
in done in an HTTP POST request.

您也可以这样使用GET,将整个网址设置为请求网址,并且不要设置HTTPBody。

NSString *urlAsString = @"http://www.getchanged.net/json.asp";
urlAsString = [urlAsString stringByAppendingString:@"?bypass=MIGCBgkrBgEEAYI3WAOxxx"];
NSURL *aUrl = [NSURL URLWithString:urlAsString];

site确认这是一个有效的JSON字符串,但其中有一些"\r\n",此代码似乎能够通过从字符串中删除"\r\n"来解决问题

NSString* receivedString = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];
receivedString = [receivedString stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];

NSData *data = [receivedString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

答案 2 :(得分:2)

我认为这就是你想要的:

NSString * bypassId = @"MIGCBgkrBgEEAYI3WAOxxx";
NSURL *aUrl = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.getchanged.net/json.asp?bypass=%@",bypassId]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSString *jsonAsString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"string: %@",jsonAsString);
    NSDictionary *jsonAsObject = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: nil];
    NSLog(@"dict: %@",jsonAsObject);
}] resume];

打印出来(在控制台中):

2014-11-06 17:09:21.659 ] string: 
{"stores":[

]}

2014-11-06 17:09:21.659 ] dict: {
    stores =     (
    );
}

我将数据打印为json字符串和字典,因为我不确定你想要什么。

答案 3 :(得分:1)

除了Rob解决的问题之外,列出的网站的JSON返回不会验证:

我已经尝试了几个带URL和旁路哈希的验证器(你在评论中发布)并且JSON无效。返回典型错误:

JSON Content: Invalid JSON at line 26, column 84
  Parse error on line 26:
  ...rtragen", "adresse":"fairtragen - GmbH 
  -----------------------^
  Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined'

json.org所述,任何字符串值都可以包含

  

除“或\或控制字符

之外的任何UNICODE字符

所以字符串值的结构如下:

enter image description here

请注意换行符和回车符所需的转义格式。

考虑到这一点,并查看Charles中捕获的原始输出,您可以看到第26行,第84列包含x0d后跟x0a(即旧的Windows样式CRLF) )在价值的中间。

服务器应该在发送之前转义这些值。

顺便说一下,JSON在数组,对象和值之外有很多空格(x 20)和CRLF,虽然不影响JSON,但是不必要,并且会对数据进行批量处理传输。

答案 4 :(得分:0)

以下工作正常:

NSURL *aUrl = [NSURL URLWithString:@"http://www.getchanged.net/json.asp?bypass=MIGCBgkrBgEEAYI3WAOxxx"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    [request setHTTPMethod:@"GET"];

    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    if (!error) {
        NSLog(@"Response String : %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

        id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSLog(@"Parsed Data : %@", json);

    }

但是可能会发生这种情况 - 正如您在笔记中提到的 - 旁路哈希被更改为隐藏您的敏感数据,该数据可能具有一些特殊字符或无效JSON,导致您的JSON解析失败。 如果您不想共享该数据,您可以使用虚拟数据编辑原始响应(不要替换特殊字符),并在此处共享,这将有助于所有人进行更多调试。