You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将获取Cookie的Python HTTP POST脚本转为Swift?遇Cookie为空问题

问题分析与解决方案

你的Swift代码无法获取Cookie的核心原因是请求体格式不匹配,同时还存在HTTPS证书验证和请求头的小问题,以下是具体修正方案:

核心问题点

  1. 请求体格式错误:你设置了Content-Type为application/x-www-form-urlencoded,但实际用JSONSerialization生成了JSON格式的请求体,服务器无法解析登录参数,导致认证失败,自然不会返回Cookie。
  2. HTTPS证书验证:Python代码关闭了证书验证(verify=False),但Swift默认会严格验证HTTPS证书,内网自签名证书环境下需要手动忽略验证。
  3. 请求头不一致:Swift中设置的Accept: application/json与Python的默认Accept: */*不符,可能导致服务器返回非预期内容。

修正后的Swift代码

import Foundation

// 辅助函数:将字典转换为x-www-form-urlencoded格式的请求体
func convertToFormData(parameters: [String: String]) -> Data? {
    let queryItems = parameters.map { URLQueryItem(name: $0.key, value: $0.value) }
    var components = URLComponents()
    components.queryItems = queryItems
    return components.query?.data(using: .utf8)
}

// 用于忽略自签名证书的Delegate(仅测试/内网环境使用)
class SelfSignedCertificateDelegate: NSObject, URLSessionDelegate {
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
            completionHandler(.useCredential, credential)
        } else {
            completionHandler(.performDefaultHandling, nil)
        }
    }
}

// 主逻辑
let auth_login = "someName"
let auth_password = "somePassword"

guard let url = URL(string: "https://192.168.0.1/passport?mode=auth") else {
    print("无效URL")
    exit(1)
}

var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("*/*", forHTTPHeaderField: "Accept") // 与Python requests默认请求头对齐
request.httpMethod = "POST"

let parameters = [
    "from": "passport",
    "retpath": "https://192.168.0.1/passport?mode=passport",
    "passwd": auth_password,
    "login": auth_login,
    "display": "page"
]

// 使用表单编码生成请求体(替代JSON序列化)
request.httpBody = convertToFormData(parameters: parameters)

// 配置支持Cookie管理和证书忽略的URLSession
let configuration = URLSessionConfiguration.default
configuration.httpCookieStorage = HTTPCookieStorage.shared
let session = URLSession(configuration: configuration, delegate: SelfSignedCertificateDelegate(), delegateQueue: nil)

let task = session.dataTask(with: request) { data, response, error in
    if let error = error {
        print("请求错误: \(error.localizedDescription)")
        return
    }
    
    guard let httpResponse = response as? HTTPURLResponse else {
        print("无效服务器响应")
        return
    }
    
    // 打印状态码,快速判断认证是否成功
    print("响应状态码: \(httpResponse.statusCode)")
    
    // 从响应头解析Cookie
    if let headerFields = httpResponse.allHeaderFields as? [String: String] {
        let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url)
        print("\n从响应头获取的Cookie:")
        cookies.forEach { print("\($0.name): \($0.value)") }
    }
    
    // 从全局Cookie存储获取(URLSession会自动管理Cookie)
    if let storedCookies = HTTPCookieStorage.shared.cookies(for: url) {
        print("\n已存储的Cookie:")
        storedCookies.forEach { print("\($0.name): \($0.value)") }
    }
    
    // 处理非2xx状态码,打印服务器返回的错误信息
    guard (200...299).contains(httpResponse.statusCode) else {
        print("\n认证失败")
        if let data = data, let responseText = String(data: data, encoding: .utf8) {
            print("服务器错误响应: \(responseText)")
        }
        return
    }
    
    print("\n认证成功")
}

task.resume()

// 保持程序运行(命令行环境需要)
RunLoop.main.run(until: Date().addingTimeInterval(10))

关键修正说明

  1. 表单编码请求体:用convertToFormData函数将参数转换为与Python requests.post(data=...)完全一致的x-www-form-urlencoded格式,确保服务器能正确解析登录参数。
  2. 证书验证处理:添加SelfSignedCertificateDelegate类忽略自签名证书验证,对应Python的verify=False(注意:生产环境禁止使用此逻辑)。
  3. 请求头对齐:将Accept头改为*/*,与Python requests的默认行为一致,避免服务器因请求头不符合预期而拒绝。
  4. 增强错误排查:添加响应内容打印,方便查看服务器返回的具体错误(比如用户名密码错误提示)。

内容的提问来源于stack exchange,提问作者RaduMod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:55:20