NSMutableURLRequest with parameter - cannot parse response

I am trying to create a URL connection that outputs JSON code which is then parsed and processed. My url has a parameter bypass

. The url looks like this:

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

I was unable to resolve this issue as it always says 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]];

      

Mistake:

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

      

What's wrong here?

Please note: I have replaced the bypass bypass because it contains reasonable data. The website runs and prints out the JSON output.

+3


source to share


5 answers


Apart from the question well covered by Rob, returning JSON from said site does not confirm:

I've tried multiple validators with url and traversal hash (you posted comments) and the JSON is not valid. Typical error:

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'

      

As explained in json.org any string value can contain

any UNICODE character except "or \ or a control character

So the string value has the following structure:



enter image description here

Note the escape format required for newlines and carriage returns.

With that in mind, and looking at the original output from Charles , you can see that line 26, column 84 contains an x0d

followed by an x0a

(i.e. the old CRLF window style) in the middle of the value.

The server MUST avoid these values ​​before sending them.

By the way, JSON has a lot of spaces (x 20

) and CRLF outside, outside the array, objects and values ​​that, without affecting JSON, are unnecessary and do not offload data transfer.

+1


source


A few observations:



  • The key issue is that you are submitting a request GET

    but providing a parameter bypass

    in the body of the request. For requests, POST

    parameters must be added to the body, but for requests, GET

    it must be added to the url.

  • If this key bypass

    may contain reserved characters (eg, spaces &

    , +

    etc.), you want to interest code has been lost, t21>. If you're guaranteed to be alphanumeric only, you can get away with no percentages by avoiding it, but as a general rule, you should always avoid HTTP parameters.

  • While point # 1 is likely to fix this problem, sometimes web services expect certain header fields to be set. For example, the Content-Type

    request header is usually set (for example, it looks like this: there Content-Type

    must be a request application/x-www-form-urlencoded

    ).

  • You say you are getting the error message: "Connection failed with error: Unable to parse response." You didn't show us the code that generates this error, but I'm guessing it was generated when your code tried to parse the response as JSON when it wasn't.

    In the future, when diagnosing these problems, I find it helpful to analyze the details of the answer. Notably, the response header will be contained in NSURLResponse

    (which actually will be NSHTTPURLResponse

    , which has a numerical value statusCode

    that can be very illuminated). The response body will often be the string representation of the error (often, when the web service fails, it generates a text or HTML description of the error).

    Whenever you get errors like this in the future, always look at statusCode

    and the text of what the server was returning, as this will help you determine what is going on. It will be more informative than the general message "I can't make out the answer".

  • If you have a web interface that works and an application interface that doesn't, it is sometimes useful to use a tool like Charles to observe the request generated by the web browser and compare it to the request generated by the application. This can be invaluable in diagnosing problems like this.

    Also, if you are using something like Charles, it allows you to manually check the status code and textual response of the server, which I assumed you could access programmatically in point 4.

+4


source


Change the request HTTPMethod

to POST

, everything will be fine.

@property (copy) NSData * HTTPBody;

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

      

You can also use GET

this way, set the whole url as the request url and don't set the HTTPBody.

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

      


This site has confirmed that this is a valid JSON string, however it does "\r\n"

, this code seems to be able to fix the problem by removing "\r\n"

from the string.

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


source


I think this is what you want:

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

      

This outputs (in the console):

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

]}

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

      

I am printing data as json string and dictionary because I'm not really sure what you want.

+2


source


The following works great:

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

    }

      

But it may be that, as you mentioned in your note, the hash bypass is changed to hide your sane data, that data might have some special characters or invalid JSON that doesn't do your JSON parsing. If you don't want to share this data, you can edit the original answer with dummy data (do not replace special characters) and share it, which will help everyone debug more.

0


source







All Articles