【问题标题】:Swift NSURLSession NSURLRequest Cookies are not acceptedSwift NSURLSession NSURLRequest Cookies 不被接受
【发布时间】:2015-07-12 15:34:25
【问题描述】:

我是 swift 和 OS X 编程的新手。对于我的第一步,我想创建一个命令行工具,它将我登录到我的移动运营商的网络界面,然后显示我剩下的数据量。我开始围绕 NSURLSession 编写一个包装器,让事情变得更容易。

问题:我的程序不接受 cookie。

我尝试了很多东西,还在会话对象上设置了 cookie 策略,但没有任何改变。如何让我的程序接受 cookie 以及如何在后续请求中使用它们?

HttpClient.swift:

import Foundation

class HttpClient {

    private var url: NSURL!
    private var session: NSURLSession

    internal init(url: String) {
        self.url = NSURL(string: url)
        self.session = NSURLSession.sharedSession()
        session.configuration.HTTPShouldSetCookies = true
        session.configuration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain
        session.configuration.HTTPCookieStorage?.cookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain
    }

    internal func sendGet() -> String {
        var ready = false
        var content: String!
        var request = NSMutableURLRequest(URL: self.url)

        var task = session.dataTaskWithRequest(request) {
            (data, response, error) -> Void in
            content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String
            ready = true
        }
        task.resume()
        while !ready {
            usleep(10)
        }
        if content != nil {
            return content
        } else {
            return ""
        }
    }

    internal func sendPost(params: String) -> String {
        var ready = false
        var content: String!
        var request = NSMutableURLRequest(URL: self.url)

        request.HTTPMethod = "POST"
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.HTTPBody = params.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
        request.HTTPShouldHandleCookies = true

        var task = session.dataTaskWithRequest(request) {
            (data, response, error) -> Void in
            content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String
            ready = true
        }
        task.resume()
        while !ready {
            usleep(10)
        }
        if content != nil {
            return content
        } else {
            return ""
        }
    }

    internal func setUrl(url: String) {
        self.url = NSURL(string: url)
    }
}

main.swift

import Foundation

let loginPage = "https://service.winsim.de/"
let dataPage = "https://service.winsim.de/mytariff/invoice/showGprsDataUsage"

var hc = HttpClient(url: loginPage)
println(hc.sendPost("usernameField=username&passwordfield=password"))
hc.setUrl(dataPage)
println(hc.sendGet())

【问题讨论】:

    标签: swift cookies login nsurlrequest nsurlsession


    【解决方案1】:

    问题解决了

    事实上,上面的代码接受cookies。我尝试登录到不同的站点并且它有效。登录也持续存在。那么为什么它不适用于我的运营商的网站?

    愚蠢的我,我的运营商有 CSRF 保护和其他我没有注意的隐藏表单字段。因此,登录不起作用。现在我知道如何解决它了。

    对于任何感兴趣的人,我会发布我更新的 HttpClient.swift 文件,希望它更整洁一些。

    请随时评论我的代码并给我一些改进提示。

    import Foundation
    
    public class HttpClient {
    
        private var session: NSURLSession
        private var request: NSMutableURLRequest
    
        public init(url: String) {
            self.session = NSURLSession.sharedSession()
            session.configuration.HTTPShouldSetCookies = true
            session.configuration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain
            session.configuration.HTTPCookieStorage?.cookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain
            self.request = NSMutableURLRequest(URL: NSURL(string: url)!)
        }
    
        public func send() -> String {
            var ready = false
            var content: String!
    
            var task = session.dataTaskWithRequest(self.request) {
                (data, response, error) -> Void in
                content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String
                ready = true
            }
            task.resume()
            while !ready {
                usleep(10)
            }
            if content != nil {
                return content
            } else {
                return ""
            }
        }
    
        public func setUrl(url: String) -> HttpClient {
            self.request.URL = NSURL(string: url)
            return self
        }
    
        public func getMethod() -> String {
            return self.request.HTTPMethod
        }
    
        public func setMethod(method: String) -> HttpClient {
            self.request.HTTPMethod = method
            return self
        }
    
        public func addFormData(data: Dictionary<String, String>) -> HttpClient {
            var params: String = ""
            var ctHeader: String? = self.request.valueForHTTPHeaderField("Content-Type")
            let ctForm: String = "application/x-www-form-urlencoded"
    
            if(data.count > 0) {
                for(name, value) in data {
                    params += name + "=" + value + "&"
                }
    
                params = params.substringToIndex(params.endIndex.predecessor())
                self.request.HTTPBody = params.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
    
                if ctHeader != nil {
                    self.request.setValue(ctForm, forHTTPHeaderField: "Content-Type")
                }
            }
    
            return self
        }
    
        public func removeFormData() -> HttpClient {
            self.request.setValue("text/html", forHTTPHeaderField: "Content-Type")
            self.request.HTTPBody = "".dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
    
            return self
        }
    }
    

    【讨论】:

    • 嗨!非常适合我。也许您可以通过替换一些未经授权的字符来改进它,因为像 @ 这样的 HTTP 参数必须是 %40 我对此没有什么问题。谢谢!
    • 这段代码是错误的。 Porperty configurationreadonlycopy 所以这段代码不会改变任何东西。要有效更改NSURLSession 配置,请使用以下方法:NSURLSession.init(configuration configuration: NSURLSessionConfiguration)
    猜你喜欢
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多