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

问题描述:

我想创建一个连接到URL,打印出JSON代码,然后解析和处理。我的网址有一个名为bypass的参数。该URL看起来是这样的:带参数的NSMutableURLRequest - 无法解析响应

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

调试此类错误的最佳方法是设置断点并实际查看服务器向您提供的响应。通常JSON解析失败,因为服务器返回一个500错误与HTML正文,如果这种情况下,你知道你的请求是错误的。否则,如果服务器返回正确的结果,那么服务器格式化响应的方式可能是一个问题 – dirkgroten 2014-11-07 12:25:01

除了由罗布很好的解决这个问题,从列出的网站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解释任何字符串值可以包含

any UNICODE character except " or \ or control character

所以一个字符串值具有作为结构是这样的:

enter image description here

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

考虑到这一点,并期待在Charles捕获的原始输出你可以看到,线26,塔84包含x0d一个值的中间,随后x0a(即旧的windows风格CRLF)。

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

顺便说一句,JSON有很多空格(x 20)和CRLF out,数组之外,对象和值,虽然不会影响JSON,但是不需要大量数据传输。

将请求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,将整个URL作为请求的url,不设置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]; 
+0

当我尝试这两种方法时,我得到:'错误域= NSCocoaErrorDomain代码= 3840“操作无法完成。 (可可错误3840.)“(JSON文本没有以数组或对象开始,并且选项允许片段未设置。)UserInfo = 0x171a6cec0 {NSDebugDescription = JSON文本没有以数组或对象开始,选项允许片段未设置。} ' – doonot 2014-11-03 17:54:34

+0

看起来像JSON文本错误,哪一行导致它?无论如何,这里是[项目](https://www.dropbox.com/s/egt2kvghezipu70/TestConnection.zip?dl=0)供参考。 – gabbler 2014-11-03 18:17:51

+0

感谢您的项目。我也得到(null)。你能检查正确的旁路散列吗? (MIGCBgkrBgEEAYI3WAOgdT) – doonot 2014-11-03 18:53:32

我想这是你想要什么:

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字符串和字典因为我不确定你想要什么。

+0

jast添加了一个代码版本的答案,有NSMutableURLRequest – mattr 2014-11-07 16:20:55

+0

令人惊叹的男人..谢谢了很多... – 2015-10-05 05:49:37

一对夫妇的意见:

  1. 的关键问题是,你发出GET请求,但在供应请求的身体bypass参数。对于POST请求,应将参数添加到主体中,但对于GET请求,应将其添加到URL中。

  2. 如果bypass关键所能包含保留的字符(如空格,&+,等等),你会想百分号逃脱你提供了bypass值。如果您确信它只有字母数字,那么您可以在没有百分比转义的情况下逃脱,但作为一般规则,您应该始终使用百分比转义HTTP参数。

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

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

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

    每当您在将来遇到类似错误时,请务必查看statusCode以及服务器返回的任何文本,因为这样可以帮助您诊断正在发生的事情。它比通用的“我无法解析响应”消息更具信息性。

  5. 如果您有一个可用的Web界面和一个不适用的应用程序界面,那么使用类似Charles这样的工具来观察Web浏览器生成的请求,并将其与由Web浏览器生成的请求进行比较应用程序。这在诊断这些问题时非常有用。另外,如果你使用Charles这样的东西,这可以让你手动检查服务器的状态码和文本响应,我建议你可以在#4中以编程方式处理。

+0

点帮助我。谢谢 – hasan83 2016-06-08 19:09:49

下正常工作:

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解析。 如果你不想共享这些数据,你可以用虚拟数据编辑原始响应(不要替换特殊字符),并在这里分享,这将有助于所有人调试更多。