POST requests in Alamofire Parameter Encoding returning GET responses

匿名 (未验证) 提交于 2019-12-03 02:34:02

问题:

I'm trying to make a Route Builder in swift using Alamofire (3.0) and I have succeded for all my GET requests, but when I try to make a POST request, for example, I still get the same responses of the GET method.

My API Routes are:

/users //GET -> return list of users /users //POST -> create new user with the parameters sent

When I use Postman everything works fine.

Here is my Router code:

import Foundation import Alamofire   enum UserRouter: URLRequestConvertible{      static let baseURL = NSURL(string: "http://192.168.0.106/users")!      case Users     case CreateUser([String: AnyObject])     case ReadUser(Int)     case UpdateUser(Int, [String: AnyObject])     case DestroyUser(Int)      var URL: NSURL { return UserRouter.baseURL.URLByAppendingPathComponent(route.path) }      var route: (path: String, parameters: [String: AnyObject]?) {          switch self{          case .Users:             return ("/", nil)         case .ReadUser(let userID):             return ("/\(userID)", nil)         case .CreateUser(let userInfo):             return ("/", userInfo)         case .UpdateUser(let userID, let userInfo):             return ("/\(userID)", userInfo)         case .DestroyUser(let userID):             return ("/\(userID)", nil)         }      }      var method: Alamofire.Method{          switch self{          case .Users:             return .GET         case .ReadUser:             return .GET         case .CreateUser:             return .POST         case .UpdateUser:             return .PUT         case .DestroyUser:             return .DELETE          }      }      var URLRequest: NSMutableURLRequest {          let httpRequest = NSMutableURLRequest(URL: URL)         httpRequest.HTTPMethod = method.rawValue          switch self{          case .CreateUser (let userInfo):             print("creating")             print(httpRequest.HTTPMethod) //Print: POST on CreateUser, like it should.             return Alamofire.ParameterEncoding.JSON.encode(httpRequest, parameters: userInfo).0         default:             return Alamofire.ParameterEncoding.URL.encode(httpRequest, parameters: (route.parameters ?? [ : ])).0          }      }  }  func testRoute(){     Alamofire.request(UserRouter.CreateUser(["name":"test"])).responseJSON{ (response) in          switch response.result{          case .Success(let data):             print (data) //Error here, printing GET response instead of my API response for creating users (POST).         case .Failure:             print("fail")         }      }  }

回答1:

Turned out that the problem was a combination of the command that Alamofire.request() generates (curl -i -X POST...) and how my Apache was handling trailing slashes of the URL. So when I tried to POST "http://192.168.0.106/users" I was being redirect (301) to a GET "http://192.168.0.106/users".

So I had to include this line of command in my .htaccess:

# Redirect Trailing Slashes... RewriteCond %{REQUEST_URI} !(.*)/$ RewriteRule ^(.*)/$ /$1 [L,R=301]

and change my Router's code, always appending a trailing slash at the end:

var route: String {          switch self{          case .Users:             return ""         case .ReadUser(let userID):             return "/\(userID)/"         case .CreateUser:             return "/"         case .UpdateUser(let userID):             return "/\(userID)/"         case .DestroyUser(let userID):             return "/\(userID)/"         }      }


回答2:

This will generate a JSON POST request. Are you sure your web service is expecting a JSON request? Make sure you don't conflate the fact that your web service returns a JSON response with the format of the request.

If your web service is expecting a standard POST request (i.e. a request with a Content-Type of application/x-www-form-urlencoded), you'd use URL for the .CreateUser, too:

var URLRequest: NSMutableURLRequest {      let httpRequest = NSMutableURLRequest(URL: URL)     httpRequest.HTTPMethod = method.rawValue      switch self {     case .CreateUser (let userInfo):         return Alamofire.ParameterEncoding.URL.encode(httpRequest, parameters: userInfo).0     default:         return Alamofire.ParameterEncoding.URL.encode(httpRequest, parameters: (route.parameters ?? [ : ])).0     }  }

If you ever have questions about whether the request was created correctly, I find that tools like Charles can be useful in confirming the precise request that was sent to the web service.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!