Question

Please excuse me if this is normal, but I am attempting to send a post request from iOS using AFNetworking. Using Charles to monitor the request, I see that a GET is sent:

GET /api/updateTeamAlert/ HTTP/1.1
Host: www.******r.co
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en;q=1, fr;q=0.9, de;q=0.8, ja;q=0.7, nl;q=0.6, it;q=0.5
Connection: keep-alive
User-Agent: ****** Alerts/1.0 (iPhone Simulator; iOS 6.1; Scale/2.00)

Is this normal? I am trying to find out why my POST parameters are empty at the server - could this be the cause?

I am creating my request like this:

NSDictionary *params = @{@"device_id":@"test-device", @"innings":@6, @"team":@"WashingtonNationals"};

[_client postPath:@"updateTeamAlert"
       parameters:params
          success:^(AFHTTPRequestOperation *operation, id responseObject)
{
    NSString *responseStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    NSLog(@"Request Successful, response '%@'", responseStr);
}
          failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
    NSLog(@"[HTTPClient Error]: %@", error.localizedDescription);
}];

UPDATE

Well, all I had to do to get this working was change the postPath to include the trailing '/' - perhaps this is obvious to most, but I would love an explanation for the accepted answer.

Was it helpful?

Solution

Well, all I had to do to get this working was change the postPath to include the trailing '/' - perhaps this is obvious to most, but I would love an explanation for the accepted answer.

PHP applications often have misconfigured servers that lose information (like HTTP method) when doing a redirect. In your case, adding the / resolved to the canonical path for your particular web service, but in redirecting to that endpoint, the POST was changed into a GET.

Another way to potentially solve this issue is to use AFURLConnectionOperation -setRedirectResponseBlock, and ensure that the redirect request has the correct verb.

OTHER TIPS

@mattt's answer above is incorrect.

HTTP/1.0 302's worked as you'd logically expect "POST /FOO" 302'd to /BAR implied that you'd get "POST /BAR". However, little to no clients implemented it this way, and commonly changed the method to GET. This is somewhat understandable as the new, redirected resource is unknown to the user, and one shouldn't POST willy nilly to an unknown resource.

HTTP/1.1 clears this up - 302's should let the user know about the redirection. 307's make the redirection work as you would expect, maintaining the method.

AFNetworking is setup to act like all the other naughty clients out there - 302's alter the method to GET, giving the client a chance to alert the user. I just had this issue with AFNetworking myself: I set up some breakpoints, stepped through, and watched the method change before my eyes.

I haven't yet tested that 307's worked as defined with AFNetworking, but regardless, 302's are behaving in the odd way that HTTP/1.1 defined them to work.

tl;dr - In HTTP/1.1 use 307's to redirect and maintain the method, not 302's.

I ran into a similar issue where every POST request was being interpreted as a GET request. It turns out, similar to servers messing up when you're missing the trailing slash, the request type can get lost when your DNS redirects www.site.com to site.com or vice versa.

In my case, my DNS forces site.com to redirect to www.site.com, but I had set my base URLs to point to site.com. Thus, when I sent a request to my API at site.com/api, the request was redirected to www.site.com/api and the request type was lost, and the server defaulted to a GET request. So I added the www to my base URL, sent my request directly to www.site.com/api (avoiding the DNS redirect), and my POST requests started working again.

TL;DR: By adding the www (or removing it, depending on your DNS) I eliminated the redirect and fixed the problem.

I facing same problem, I using Laravel for server.

If my request is "http://localhost/api/abc/" then POST method send from client will became GET method in Server. But if my request is "http://localhost/api/abc" (without "/"), then server will receive POST method.

I founded root cause is because of Redirect rule in .htaccess file: In my .htaccess have these lines:

# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

These lines will change POST method to GET method if request have "/" in the end. To fix this issue, I just comment out these lines. Hope this help.

Another case you will encounter this issue is that when you set up redirection from HTTP to HTTPS automatically, the POST request will be redirected as GET request if this redirection setup is at work. Just updating your API endpoint to HTTPS resolves this case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top