0

在用户在第一个 WebView 上获得授权后,我需要在第二个 WebView 上使用相同的配置(cookie)。在模拟器上运行良好,但在设备上不稳定。

class auth: UIViewController, WKNavigationDelegate, UIWebViewDelegate {
private var webView: WKWebView = WKWebView()
    override func viewDidLoad() {
        super.viewDidLoad()
        webView.navigationDelegate = self
        loadPage(urlString: link)
    }
    private func loadPage(urlString: String) {
        if let encodedURL = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
            let url = URL(string: encodedURL) {
            let request = URLRequest(url: url)
            webView.refreshCookies()
            webView.load(request)
        }
    }
}

extension WKWebView {
    func refreshCookies() {
        self.configuration.websiteDataStore = WKWebsiteDataStore.default()
    }
}
4

3 回答 3

1

您可以在共享的 HTTPCookieStorage 中设置 cookie,而不是像上面提到的那样保留全局 cookie 变量或保存到 plist。

储藏:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

    let request = navigationAction.request
    let url = request.url

    webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { (cookies) in
         HTTPCookieStorage.shared.setCookies(cookies, for: url, mainDocumentURL: nil)
    }

    decisionHandler(.allow)
    return
}

并检索和设置(在不同的 WebView 实例中):

let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) 
let config = WKWebViewConfiguration()
let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
    config.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
}

let webView2 = WKWebView(frame: frame, configuration: config)

希望这会有所帮助

于 2019-10-26T03:07:47.010 回答
1

每个 ** WKWebView** 都有自己的 cookie 空间,cookie 空间保存在WKProcessPool中,只需将进程池对象设为全局并分配给每个 webview 对象,希望这适用于您的情况。

    static let processPool = WKProcessPool()

并且每次都使用这个进程池设置你的 WKWebView 实例,另一种方法是每当你创建 wkwebview 并加载时实现这个功能。

 func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    // use to sync cookies
    guard let response = navigationResponse.response as? HTTPURLResponse, let responseUrl = navigationResponse.response.url else {
        decisionHandler(.cancel)
        return
    }

    if #available(iOS 11.0, *) {
        self.webView.httpCookieStore.getAllCookies { (cookies) in
            cookies.forEach({ (cookie) in
                if cookie.name == Constant.appCodeCookie || cookie.name == Constant.rpgaCookieName || cookie.name == Constant.headerCookie , cookie.name == Constant.adIdCookie {
                    HTTPCookieStorage.shared.setCookie(cookie)
                }
            })
        }

    } else {
        // Fallback version
        if  let allHttpHeaders = response.allHeaderFields as? [String: String] {
            let cookies = HTTPCookie.cookies(withResponseHeaderFields: allHttpHeaders, for: responseUrl)
            for cookie in cookies {
                HTTPCookieStorage.shared.setCookie(cookie)
            }
        }
    }


    decisionHandler(.allow)
}

每次创建 wkwebview 实例时,只需从 httpcookiestorage 获取所有 cookie 并在 wkwebview 用户脚本中进一步设置,您也可以在此处查看我的答案。我可以设置 WKWebView 使用的 cookie 吗?

于 2018-09-25T05:12:17.950 回答
0

您需要为每个 wkwebview 设置 cookie,因此将 cookie 值保留为全局变量或将其保存在 plist 中。

于 2018-09-22T14:38:07.873 回答