使用 Alamofire 2.0 请求失败
Posted
技术标签:
【中文标题】使用 Alamofire 2.0 请求失败【英文标题】:Put request failing with Alamofire 2.0 【发布时间】:2015-09-15 21:33:12 【问题描述】:我最近升级到 Alamofire 2.0
,现在我的 Put 请求失败并出现 400 错误,而之前它可以正常工作。我使用代码执行调用:
Alamofire.request(Router.Put(query: url, params: params, encoding: .JSON))
.validate()
.responseJSON()
(request, response, result) in
print("request: \(request)")
print("response: \(response)")
print("result: \(result)")
switch result
case .Success(_):
// success
case .Failure(let data, _):
// error occured
还有我的自定义路由器类:
enum Router: URLRequestConvertible
case Get(query: String, params: [String: AnyObject]?)
case Post(query: String, params: [String: AnyObject]?)
case Put(query: String, params: [String: AnyObject]?, encoding: ParameterEncoding)
case Delete(query: String, params: [String: AnyObject]?)
var URLRequest: NSMutableURLRequest
var encodeMethod: Alamofire.ParameterEncoding = Alamofire.ParameterEncoding.URL
// Default to GET
var httpMethod: String = Alamofire.Method.GET.rawValue
let (path, parameters): (String, [String: AnyObject]?) =
switch self
case .Get(let query, let params):
// Set the request call
httpMethod = Alamofire.Method.GET.rawValue
// Return the query
return (query, params)
case .Post(let query, let params):
// Set the request call
httpMethod = Alamofire.Method.POST.rawValue
// Return the query
return (query, params)
case .Put(let query, let params, let encoding):
// Set the request call
httpMethod = Alamofire.Method.PUT.rawValue
// Set the encoding
encodeMethod = encoding
// Return the query
return (query, params)
case .Delete(let query, let params):
// Set the request call
httpMethod = Alamofire.Method.DELETE.rawValue
// Return the query
return (query, params)
()
// Create the URL Request
let URLRequest = NSMutableURLRequest(URL: NSURL(string: Globals.BASE_URL + path)!)
// set header fields
if let key = NSUserDefaults.standardUserDefaults().stringForKey(Globals.NS_KEY_SESSION)
URLRequest.setValue(key, forHTTPHeaderField: "X-XX-API")
// Add user agent
if let userAgent = NSUserDefaults.standardUserDefaults().stringForKey(Globals.NS_KEY_USER_AGENT)
URLRequest.setValue(userAgent, forHTTPHeaderField: "User-Agent")
// Set the HTTP method
URLRequest.HTTPMethod = httpMethod
URLRequest.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
return encodeMethod.encode(URLRequest, parameters: parameters).0
响应不是成功,而是:
response: Optional(<NSHTTPURLResponse: 0x7fcee15b34d0> URL: https://apiurl status code: 400, headers
"Cache-Control" = "no-cache";
"Content-Length" = 26;
"Content-Type" = "application/json; charset=utf-8";
Date = "Tue, 15 Sep 2015 15:33:50 GMT";
Expires = "-1";
Pragma = "no-cache";
Server = "Microsoft-IIS/8.5";
)
我调查了问题,在服务器端,Content-Type
以空白的形式出现,而它应该以 application/json
的形式出现。当请求中有正文数据时,Content-Type
应该会自动添加。我设置了参数:
// Save the profile
var params: [String: AnyObject] = ["indexPhoto": userProfile.indexPhoto,
"dob": df.stringFromDate(userProfile.dob) as NSString,
"identAs": userProfile.identAs]
// Add manually since creating the dictionary all at once is too much for swift to handle
params.updateValue(String(format:"%.2f", userProfile.heightIn), forKey: "heightIn")
params.updateValue(String(format:"%.2f", userProfile.weightLbs), forKey: "weightLbs")
params.updateValue(userProfile.eyes, forKey: "eyes")
params.updateValue(userProfile.hair, forKey: "hair")
...
有什么我可能会错过的吗?在我升级到Alamofire 2.0
之前,这个电话工作得很好。
【问题讨论】:
您能否发布您正在使用Alamofire.request
调用创建的Request
的debugPrint
输出?那肯定会有所帮助。此外,您应该尝试使用该 cURL 来查看是否可以按预期访问您的服务器。
$ curl -i \ -X PUT \ -H "Content-Type: application/json" \ -H "User-Agent: Mozilla/5.0 (ios 9.1; en_US; [en]) BC /2.0.0.40" \ -H "X-XX-API: myApp x-XX-api 值" \ -H "Accept-Language: en-US;q=1.0" \ -H "Accept-Encoding: gzip;q =1.0,compress;q=0.5" \ -H "用户代理:myAppUserAgent (40;操作系统版本 9.1 (Build 13B5110e))" \ -d "\"hShowCity\":true,\"langs\":\ "168|169\", ... \"dob\":\"1982-11-18T00:00:00\"" \ "myAppApi/member/profile/edit"
我使用了debugDescription
,因为Request
没有debugPrint
。我删掉了一些参数,因为所有参数都在那里,评论太长而无法发布。这个 API 已经在生产中,所以我知道端点确实可以工作。我确实注意到有两个 User-Agent
值。
@cnoon 我们最终找出了错误所在。感谢您在使用“debugDescription”方面的帮助。在服务器端工作的人需要一个应该被贬低的变量。它没有伤害任何东西,但是我们如何替换“User-Agent”而不是拥有第二个标头值?
您可以通过在Request
上设置User-Agent
标头(请求标头覆盖配置)或不在NSURLSessionConfiguration
上设置它来覆盖User-Agent
。
【参考方案1】:
也许有不同的方法,但我通过发送空参数而不是 nil 解决了同样的问题。我在使用 .PUT 时不使用任何参数,因为该服务器不知道如何编码请求和响应(即使我在标头中明确设置内容类型,我在服务器上收到空白内容类型)所以我的解决方案是像下面的代码一样发送空参数。希望它可以帮助某人。
var url = https://api.mysite.com/v1/issue/369613/delete
let params = ["":""]
let headers = NetworkConnection.addAuthorizationHeader(token, tokenType: tokenType)
manager.request(.PUT, url, parameters: params, encoding: .JSON, headers: headers)
.responseJSON response in
if let JSONdata = response.result.value
print("JSONdata: \(JSONdata)")
【讨论】:
以上是关于使用 Alamofire 2.0 请求失败的主要内容,如果未能解决你的问题,请参考以下文章
转换为 swift 2.0 时,构建的 Alamofire 3 失败