REST API的问题

时间:2018-02-23 11:05:36

标签: ios iphone rest ipad swift3

我正在使用REST API's中的iOS application

我测试了Server URL方法的ParametersPOST

返回

您的浏览器发送了此服务器无法理解的请求

响应中出现此错误。

对于GET请求API工作正常。 如果有人遇到同样的问题,请告诉我。

谢谢。

请检查我的网络服务模式

let configuration = URLSessionConfiguration.default;
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
var urlString = String()
urlString.append(Constant.BASE_URL)
urlString.append(methodName)

let encodedUrl = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let serverUrl: URL = URL(string: (encodedUrl?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed))!)!
var request : URLRequest = URLRequest(url: serverUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)
var paramStr : String = String()
if requestDict.count > 0 {
    let keysArray = requestDict.keys
    for  key in keysArray {
        if paramStr.isEmpty{
            paramStr.append("\(key)=\(requestDict[key]! as! String)")
        }else{
            paramStr.append("&\(key)=\(requestDict[key]! as! String)")
        }
    }
}

let postData:Data = try! JSONSerialization.data(withJSONObject: requestDict)//paramStr.data(using: .utf8)!
let reqJSONStr = String(data: postData, encoding: .utf8)
let postLength = "\(postData.count)"

request.httpMethod = "POST"
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
//request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
//request.httpBody = reqJSONStr?.data(using: .utf8)

request.setValue("application/json", forHTTPHeaderField: "Content-Type")

request.httpBody = try! JSONSerialization.data(withJSONObject: requestDict)



if  headerValue != nil{
    let allkeys = headerValue.keys
    for key in allkeys {
        request.setValue(headerValue[key] as! String?, forHTTPHeaderField: key)
    }
}

let postDataTask : URLSessionDataTask = session.dataTask(with: request, completionHandler:
{
    data, response, error in
    if data != nil && error == nil{
        let res = String(data: data!, encoding: .utf8)
        let dict = convertToDictionary(text: res!)
        if let httpResponse = response as? HTTPURLResponse {
            //print("error \(httpResponse.statusCode)")
            if httpResponse.statusCode == 200
            {
                DispatchQueue.main.async {
                    successBlock (response!,(dict)!)
                }
            }
            else
            {
                if (error?.localizedDescription) != nil
                {
                    errorBlock((error?.localizedDescription)! as String)
                }
                else
                {
                    errorBlock("")
                }
            }
        }
        else
        {
            errorBlock((error?.localizedDescription)! as String)
        }
    }
    else{
        if let httpResponse = error as? HTTPURLResponse {
            //print("error \(httpResponse.statusCode)")
        }
        errorBlock((error?.localizedDescription)! as String)
    }
})
postDataTask.resume()

1 个答案:

答案 0 :(得分:1)

假设你的后端期望一个form-urlencoded请求,那么你应该在字符串url编码中转换你的参数字典

这是一个例子

let parameters : [String:Any] = ["ajax":1,"test":"abuela"]

var queryItems : [URLQueryItem] = []
for key in parameters.keys {
    if let value = parameters[key] as? String {
        queryItems.append(URLQueryItem(name: key, value: value))
    }else{
        queryItems.append(URLQueryItem(name: key, value: String(describing:parameters[key]!)))
    }
}

var urlComponents = URLComponents()
urlComponents.queryItems = queryItems

然后,如果你

print(urlComponents.percentEncodedQuery!)

你会得到

  

test=abuela&ajax=1

然后使用此功能,您需要添加urlString

urlString.append("&" + urlComponents.percentEncodedQuery!)

完整代码

let configuration = URLSessionConfiguration.default;
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
var urlString = String()
urlString.append(Constant.BASE_URL)
urlString.append(methodName)

var queryItems : [URLQueryItem] = []
for key in parameters.keys {
    if let value = parameters[key] as? String {
        queryItems.append(URLQueryItem(name: key, value: value))
    }else{
        queryItems.append(URLQueryItem(name: key, value: String(describing:parameters[key]!)))
    }
}

var urlComponents = URLComponents()
urlComponents.queryItems = queryItems

print(urlComponents.percentEncodedQuery!)
urlString.append("&" + urlComponents.percentEncodedQuery!)

let encodedUrl = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let serverUrl: URL = URL(string: urlString)!
var request : URLRequest = URLRequest(url: serverUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)


request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

let postDataTask : URLSessionDataTask = session.dataTask(with: request, completionHandler:
{
    data, response, error in
    if data != nil && error == nil{
        let res = String(data: data!, encoding: .utf8)
        let dict = convertToDictionary(text: res!)
        if let httpResponse = response as? HTTPURLResponse {
            //print("error \(httpResponse.statusCode)")
            if httpResponse.statusCode == 200
            {
                DispatchQueue.main.async {
                    successBlock (response!,(dict)!)
                }
            }
            else
            {
                if (error?.localizedDescription) != nil
                {
                    errorBlock((error?.localizedDescription)! as String)
                }
                else
                {
                    errorBlock("")
                }
            }
        }
        else
        {
            errorBlock((error?.localizedDescription)! as String)
        }
    }
    else{
        if let httpResponse = error as? HTTPURLResponse {
            //print("error \(httpResponse.statusCode)")
        }
        errorBlock((error?.localizedDescription)! as String)
    }
})
postDataTask.resume()

如果你的后端正在等待application/json http body encoded

你正在httpBody中传递一个JSON对象,但是你的contentType标题是错误的而不是"application/x-www-form-urlencoded"应该是"application/json",我认为你的json转换错误尝试直接使用你的requestDict并{{1}将在您可以在JSONSerialization

中使用的有效JSON对象中转换字典

替换

request.httpBody

request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

使用此命令将您的requestDict参数字典转换为JSON

request.setValue("application/json", forHTTPHeaderField: "Content-Type")