Swift中发送GET/PUT/POST请求的相关技术问题咨询
先针对你POST XML的疑问逐一解答:
POST XML 请求疑问
是否需要手动设置Content-Length?
完全不需要!URLSession会自动计算请求体的字节长度并添加Content-Length头。手动设置反而容易出错——比如你用xml.count得到的是字符串的字符数,但UTF-8编码下部分字符(比如中文)会占多个字节,导致长度不匹配,后端可能解析失败。直接删掉手动设置的这个头就好。能否在发送XML的同时携带参数?
当然可以,两种常见方式:- 把参数放在URL的查询字符串里(就像你GET请求里的
ws_key=ABC...XYZ那样),后端可以从URL中解析这些参数; - 如果后端支持,把参数嵌入到XML内容里(比如在XML根节点里加
<params><key1>value1</key1></params>);
具体用哪种看后端API的约定。
- 把参数放在URL的查询字符串里(就像你GET请求里的
需要设置哪些请求头?
核心只需要设置Content-Type:可以用text/xml; charset=utf-8或者application/xml(这两个都是标准的XML媒体类型,多数后端都支持,具体看API文档要求)。其他头(比如Host、Connection)URLSession会自动帮你处理,除非后端有特殊要求,否则不用额外添加。请求体需要什么结构和编码方式?
不需要包装成xml=<?xml...这种form-urlencoded格式!直接把XML原始字符串转成UTF-8编码的Data就行。比如用xml.data(using: .utf8)来获取正确的请求体数据,不需要手动做addingPercentEncoding——XML本身是纯文本,UTF-8编码就能正确传递。
PUT XML 请求疑问
你遇到的String could not be parsed as XML, XML length: 0错误,大概率是请求体没有正确传递(比如Data为空)。针对你的疑问:
需要设置哪些请求头?
和POST一致,核心设置Content-Type为text/xml; charset=utf-8或application/xml,同样不需要手动设置Content-Length。请求体需要什么结构和编码方式?
和POST完全相同:直接传递XML的UTF-8编码Data,不需要额外包装,也不需要做percent编码。确保你的XML字符串不为空,且转成Data成功(xml.data(using: .utf8)不为nil)。
完整示例代码
1. POST XML 请求示例
class func postXML(xml: String, completionHandler: @escaping (Data?, Error?) -> Void) { let urlString = "https://example.com/api/someResource?ws_key=ABC...XYZ" guard let url = URL(string: urlString) else { completionHandler(nil, NSError(domain: "Invalid URL", code: -1, userInfo: nil)) return } var request = URLRequest(url: url) request.httpMethod = "POST" // 设置Content-Type request.setValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type") // 把XML转成UTF-8 Data作为请求体 guard let httpBody = xml.data(using: .utf8) else { completionHandler(nil, NSError(domain: "Invalid XML Data", code: -2, userInfo: nil)) return } request.httpBody = httpBody URLSession.shared.dataTask(with: request) { data, response, error in completionHandler(data, error) // 如果需要解析返回的JSON或XML,可以在这里处理 }.resume() }
2. PUT XML 请求示例
class func putXML(xml: String, completionHandler: @escaping (Data?, Error?) -> Void) { let urlString = "https://example.com/api/someResource?ws_key=ABC...XYZ" guard let url = URL(string: urlString) else { completionHandler(nil, NSError(domain: "Invalid URL", code: -1, userInfo: nil)) return } var request = URLRequest(url: url) request.httpMethod = "PUT" // 设置Content-Type request.setValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type") // 把XML转成UTF-8 Data作为请求体 guard let httpBody = xml.data(using: .utf8) else { completionHandler(nil, NSError(domain: "Invalid XML Data", code: -2, userInfo: nil)) return } request.httpBody = httpBody URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("PUT请求错误:\(error.localizedDescription)") completionHandler(nil, error) return } completionHandler(data, nil) // 处理返回数据 }.resume() }
使用时,你只需要传入你的XML字符串,然后在completionHandler里处理返回的结果即可。如果后端返回JSON,你可以像之前GET请求那样用JSONDecoder解析;如果返回XML,你可以用XMLParser来处理。
内容的提问来源于stack exchange,提问作者Yuma Technical Inc.

