REST API 的问题

REST API's issue

我正在 REST API's iOS application 中工作。

我已经测试了POST方法的Server URLParameters

返回

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

这个响应错误。

对于 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()

假设您的后端期待一个 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 编码

你在 httpBody 中传递了一个 JSON object 但你的 contentType header 是错误的而不是 "application/x-www-form-urlencoded" 应该是 "application/json",我认为你的json 转换错误尝试直接使用您的 requestDict,JSONSerialization 会将字典转换为有效的 JSON object,您可以在 request.httpBody[=25] 中使用=]

替换

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

通过

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

使用它来转换为 JSON 你的 requestDict 参数字典

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