我正在尝试创建一个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输出。
答案 0 :(得分:4)
有几点意见:
关键问题是您发出了GET
请求,但在请求正文中提供了bypass
参数。对于POST
个请求,应将参数添加到正文中,但对于GET
个请求,应将其添加到网址中。
如果此bypass
键可能包含保留字符(例如空格,&
,+
等),则您希望百分比转义您为bypass
提供的价值。如果你保证它只是字母数字,你就可以逃脱而不会逃避它,但作为一般规则,你应该总是百分之百地逃避HTTP参数。
虽然第1点可能会解决此问题,但有时Web服务会期望设置某些标头字段。例如,通常会设置请求的Content-Type
标头(例如,看起来请求的Content-Type
应为application/x-www-form-urlencoded
)。
您说您收到错误消息,"连接失败并显示错误:无法解析响应"。您还没有向我们展示产生此错误的代码,但我认为这是在您的代码尝试将响应解析为JSON时生成的。
将来,在诊断这些问题时,我发现实际检查响应的详细信息很有用。值得注意的是,响应的标题将包含在NSURLResponse
中(实际上是NSHTTPURLResponse
,其statusCode
数值非常明显。响应的主体通常是错误的字符串表示(通常当Web服务失败时,它会生成错误的文本或HTML描述)。
每当您将来遇到这样的错误时,请始终查看statusCode
以及服务器返回的文本,因为这有助于您诊断正在进行的操作。它将比通用的更具信息性#34;我无法解析响应"消息。
如果您的网络界面有效,而且应用程序界面不起作用,那么使用像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字符
所以字符串值的结构如下:
请注意换行符和回车符所需的转义格式。
考虑到这一点,并查看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解析失败。 如果您不想共享该数据,您可以使用虚拟数据编辑原始响应(不要替换特殊字符),并在此处共享,这将有助于所有人进行更多调试。