post - 使用 POST 方法在 Swift 中进行 HTTP 请求

标签 post swift parameters http-post httprequest

我正在尝试在 Swift 中运行 HTTP 请求,以将 2 个参数发布到 URL。

例子:

链接:www.thisismylink.com/postName.php

参数:

id = 13
name = Jack

最简单的方法是什么?

我什至不想阅读回复。我只想发送它以通过 PHP 文件对我的数据库执行更改。

最佳答案

关键是你要:

  • httpMethod设置为POST
  • 可选地,设置 Content-Type header ,以指定请求主体的编码方式,以防服务器可能接受不同类型的请求;
  • 可选地,设置Accept header ,以请求响应主体应如何编码,以防服务器可能生成不同类型的响应;和
  • httpBody 设置为针对特定的 Content-Type 进行正确编码;例如如果 application/x-www-form-urlencoded 请求,我们需要对请求正文进行百分比编码。

例如,在 Swift 3 及更高版本中,您可以:

let url = URL(string: "https://httpbin.org/post")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
let parameters: [String: Any] = [
    "id": 13,
    "name": "Jack & Jill"
]
request.httpBody = parameters.percentEncoded()

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard 
        let data = data, 
        let response = response as? HTTPURLResponse, 
        error == nil 
    else {                                                               // check for fundamental networking error
        print("error", error ?? URLError(.badServerResponse))
        return
    }
    
    guard (200 ... 299) ~= response.statusCode else {                    // check for http errors
        print("statusCode should be 2xx, but is \(response.statusCode)")
        print("response = \(response)")
        return
    }
    
    // do whatever you want with the `data`, e.g.:
    
    do {
        let responseObject = try JSONDecoder().decode(ResponseObject<Foo>.self, from: data)
        print(responseObject)
    } catch {
        print(error) // parsing error
        
        if let responseString = String(data: data, encoding: .utf8) {
            print("responseString = \(responseString)")
        } else {
            print("unable to parse response as string")
        }
    }
}

task.resume()

以下扩展有助于百分比编码请求主体,将 Swift Dictionary 转换为 application/x-www-form-urlencoded 格式的 Data:

extension Dictionary {
    func percentEncoded() -> Data? {
        map { key, value in
            let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
            let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
            return escapedKey + "=" + escapedValue
        }
        .joined(separator: "&")
        .data(using: .utf8)
    }
}

extension CharacterSet { 
    static let urlQueryValueAllowed: CharacterSet = {
        let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
        let subDelimitersToEncode = "!$&'()*+,;="
        
        var allowed: CharacterSet = .urlQueryAllowed
        allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
        return allowed
    }()
}

下面的Decodable 模型对象使用JSONDecoder 促进了application/json 响应的解析:

// sample Decodable objects for https://httpbin.org

struct ResponseObject<T: Decodable>: Decodable {
    let form: T    // often the top level key is `data`, but in the case of https://httpbin.org, it echos the submission under the key `form`
}

struct Foo: Decodable {
    let id: String
    let name: String
}

这会检查基本网络错误和高级 HTTP 错误。这也正确地对查询参数进行了百分比转义。

请注意,我使用了 Jack & Jillname 来说明 的正确 x-www-form-urlencoded 结果>name=Jack%20%26%20Jill,这是“百分比编码”(即空格替换为 %20 和值中的 &替换为 %26)。


参见 previous revision of this answer用于 Swift 2 版本。

关于post - 使用 POST 方法在 Swift 中进行 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26364914/

相关文章:

python - 计算列表平均值并返回大于整个列表数学平均值的元素的函数

node.js - Node 管道停止工作

swift - Alamofire 在 swift 中解析和连接 JSON

python - 使用 Scrapy Request 上传验证码图片

node.js - JSONSerialization 生成不正确的 JSON 对象。 swift

ios - 我可以从哪里获得 CommonCrypto/CommonCrypto 文件?

Delphi如何以单个字符串形式检索所有参数

java - 在 Spring Controller 中使用日期参数的最佳实践?

REST API - 客户端如何知道发布到资源的有效负载是什么?

c++ - HTTP POST 中缺少内容类型。 QT使用Webview