簡體   English   中英

無法設置WKWebView設置Cookie(iOS 11+)

[英]WKWebView setting Cookie not possible (iOS 11+)

我拼命試圖將自定義cookie添加到WKWebView實例(不使用Javascript或類似的解決方法)。

從iOS 11及更高版本開始,Apple提供了執行此操作的API: WKWebViewWKWebsiteDataStore具有屬性httpCookieStore

這是我的(示例)代碼:

import UIKit
import WebKit

class ViewController: UIViewController {

    var webView: WKWebView!

    override func viewDidLoad() {
        webView = WKWebView()
        view.addSubview(webView)
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        let cookie = HTTPCookie(properties: [
            HTTPCookiePropertyKey.domain : "google.com",
            HTTPCookiePropertyKey.path : "/",
            HTTPCookiePropertyKey.secure : true,
            HTTPCookiePropertyKey.name : "someCookieKey",
            HTTPCookiePropertyKey.value : "someCookieValue"])!

        let cookieStore = webView.configuration.websiteDataStore.httpCookieStore
        cookieStore.setCookie(cookie) {
            DispatchQueue.main.async {
                self.webView.load(URLRequest(url: URL(string: "https://google.com")!))
            }
        }
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        webView.frame = view.bounds
    }
}

此后,如果我使用webView.configuration.websiteDataStore.httpCookieStore.getAllCookies(completionHandler:)我會看到我的cookie在cookie列表中。

但是,當使用Safari的開發人員工具(當然使用iOS模擬器)檢查Web視圖時,cookie不會顯示。

我還嘗試使用HTTP代理(在本例中為Charles)檢查流量,以查看cookie是否包含在我的HTTP請求中。 它不是。

我在這里做錯了什么? 如何將cookie添加到WKWebView (在iOS 11及更高版本上)?

有點晚了,但是我想分享一個對我有用的解決方案,希望它也可以幫助在iOS 12上也面臨相同問題的人。

這是我使用的簡化工作流程:

  1. 實例化WKWebsiteDataStore對象
  2. 將自定義Cookie設置為其httpCookieStore
  3. 等待cookie被設置
  4. 實例化WKWebView
  5. 加載請求

為此,我創建了WKWebViewConfiguration的擴展:

extension WKWebViewConfiguration {

static func includeCookie(cookie:HTTPCookie, preferences:WKPreferences, completion: @escaping (WKWebViewConfiguration?) -> Void) {
     let config = WKWebViewConfiguration()
     config.preferences = preferences

     let dataStore = WKWebsiteDataStore.nonPersistent()

     DispatchQueue.main.async {
        let waitGroup = DispatchGroup()

        waitGroup.enter()
        dataStore.httpCookieStore.setCookie(cookie) {
            waitGroup.leave()
        }

        waitGroup.notify(queue: DispatchQueue.main) {
            config.websiteDataStore = dataStore
            completion(config)
        }
    }
}

對於我的示例,我使用它的方式如下:

override func viewDidLoad() {
  self.AddWebView()
}

private func addWebView(){

    let preferences = WKPreferences()
    preferences.javaScriptEnabled = true
    preferences.javaScriptCanOpenWindowsAutomatically = true

    let cookie = HTTPCookie(properties: [
        .domain: COOKIE_DOMAIN,
        .path: "/",
        .name: COOKIE_NAME,
        .value: myCookieValue,
        .secure: "TRUE",
        .expires: NSDate(timeIntervalSinceNow: 3600)
        ])

     //Makes sure the cookie is set before instantiating the webview and initiating the request
     if let myCookie = cookie {
        WKWebViewConfiguration.includeCookie(cookie: myCookie, preferences: preferences, completion: {
           [weak self] config in
              if let `self` = self {
                 if let configuration = config {
                    self.webView = WKWebView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width , height: self.view.frame.height), configuration: configuration)

                    self.view.addSubview(self.webView)
                    self.webView.load(self.customRequest)
                 }
              }
     }
}

google.com任何請求都將重定向到www.google.com

您將需要添加www. 到cookie的domain字段。 如果域或路徑與請求不匹配,則不會發送cookie。

您可以顯式添加cookie。

let url = URL(string: "https://www.google.com")!
var request = URLRequest(url: url)
if let cookies = HTTPCookieStorage.shared.cookies(for: url) {
    request.allHTTPHeaderFields = HTTPCookie.requestHeaderFields(with: cookies)
}
self.webView.load(request)

對於iOS 11或更高版本,您真的不需要擔心cookie的一部分,這非常簡單。 像這樣創建您的cookie。 不要確保它是真的

let newcookie = HTTPCookie(properties: [
        .domain: "domain",
        .path: "/",
        .name: "name",
        .value: "vale",
        .secure: "FALSE",
        .expires: NSDate(timeIntervalSinceNow: 31556926)
        ])!

self.webview.configuration.websiteDataStore.httpCookieStore.setCookie(newcookie, completionHandler: {
                        // completion load your url request here. Better to add cookie in Request as well. like this way
       request.addCookies()
//enable cookie through request
        request.httpShouldHandleCookies = true

//load request in your webview.


                    })

請求擴展在cookie值“;”之后添加

extension URLRequest {

internal mutating func addCookies() {
    var cookiesStr: String = ""

        let mutableRequest = ((self as NSURLRequest).mutableCopy() as? NSMutableURLRequest)!
            cookiesStr += cookie.name + "=" + cookie.value + ";"                

            mutableRequest.setValue(cookiesStr, forHTTPHeaderField: "Cookie")
            self = mutableRequest as URLRequest

     }

}

我也可以看到您沒有設置wkwebview的WKWebViewConfiguration。 設置您的wkwebview的配置。 還實現WKHTTPCookieStoreObserver並實現功能。

    func cookiesDidChange(in cookieStore: WKHTTPCookieStore) {
    // Must implement otherwise wkwebview cookie not sync properly
    self.httpCookieStore.getAllCookies { (cookies) in
        cookies.forEach({ (cookie) in

        })
    }
}

希望這樣會起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM