alamofire 发送 xml 请求需手动设置 content-type 为 application/xml 并传入 data 类型的 xml 内容,不能使用 parameters 参数;接收 xml 响应时应避免 responsedecodable,改用 responsestring 后解析。

Alamofire 发送 XML 请求时 Content-Type 总是被忽略
Alamofire 默认不识别 XML,Content-Type 不会自动设为 application/xml,哪怕你传了 XML 字符串,它默认按 application/x-www-form-urlencoded 发——后端收不到原始 XML,直接 400 或解析失败。
必须手动覆盖请求头:
- 用
URLRequest构造请求,再传给AF.request(_:),不能直接传 URL 和参数字典 urlRequest.setValue("application/xml", forHTTPHeaderField: "Content-Type")- XML 数据得是
Data类型(不是String),否则 Alamofire 可能二次编码或截断特殊字符
XML 字符串转 Data 容易出乱码或格式错乱
iOS 上默认用 UTF-8 编码,但 XML 声明里如果写了 <?xml version="1.0" encoding="UTF-8"?>,而实际数据用了其他编码(比如从服务器拉来的旧 XML 含 GBK 字节),data(using: .utf8) 就会返回 nil 或乱码。
安全做法:
- 确认 XML 源头编码,优先统一用 UTF-8 生成和传输
- 构造 XML 时别手拼,用
XMLDocument或XMLWriter类库生成,避免引号、尖括号、CDATA 写错 - 如果必须用字符串转
Data,加容错:xmlString.data(using: .utf8, allowLossyConversion: true),但要清楚丢失字符的风险
Alamofire 5+ 版本里 request() 不接受 raw body 参数
老教程常写 AF.request(url, method: .post, parameters: xmlData, encoder: URLEncodedFormParameterEncoder()) ——这根本发不出 XML。parameters 是给表单或 JSON 用的,传 Data 会被当成键值对 key 处理,最终发出去的是空或非法 body。
正解是绕过高层封装:
- 先创建
var urlRequest = URLRequest(url: yourURL) urlRequest.httpMethod = "POST"urlRequest.httpBody = xmlDataurlRequest.setValue("application/xml", forHTTPHeaderField: "Content-Type")- 再调用
AF.request(urlRequest)
服务端返回 XML 但 Alamofire 自动解析成 JSON 导致崩溃
有些后端不管返回什么内容,都设 Content-Type: application/xml,但 Alamofire 的 responseDecodable 默认尝试 JSON 解析,遇到 XML 标签就抛 JSONSerialization error,错误信息像 Invalid value around character 0。
必须显式指定响应处理方式:
- 用
responseString()拿原始文本,再用XMLDocument(data: ..., options: ...)解析 - 不要用
responseDecodable,除非你写了专门适配 XML 的Decodable扩展(极少见且维护成本高) - 检查响应头:如果后端返回
text/xml而非application/xml,也要同步改setValue的值,否则可能被某些中间件拦截
XML 的边界其实很脆:编码、声明、空格、命名空间、CDTD,任一环节不对,整条链路就静默失败。别信“发过去就行”,每次都要抓包看真实请求体和响应体长什么样。










