swift 如何将启用Cookie添加到WKWebView

pxq42qpu  于 2022-12-02  发布在  Swift
关注(0)|答案(1)|浏览(328)

我在WKWebView中得到了一个加载带有url的html内容的要求。我正在尝试用loadHTMLString加载该内容,页面正在加载,但出现错误,如需要启用third-partycookiesWKWebView
是否可以在WKWebView中允许Third-Party Cookie。

let url =
"https://www.ck12.org/lms-integration-service/prod/gcaddon.html?launch_key=21C8B2B198A2ABAEE5C97228EBD90836F6BFB34BD1E4302F6762FF7D12F8D904CDA084B4737EF781A18FC25E4F17EA34&app=ltiApp&extra=eyJyZWRpcmVjdCI6Imh0dHBzOi8vZmxleGJvb2tzLmNrMTIub3JnL2Nib29rL2NrLTEyLW1pZGRsZS1zY2hvb2wtZWFydGgtc2NpZW5jZS1mbGV4Ym9vay0yLjAvc2VjdGlvbi8xLjEvcHJpbWFyeS9sZXNzb24vc2NpZW50aWZpYy1leHBsYW5hdGlvbnMtYW5kLWludGVycHJldGF0aW9ucy1tcy1lcy8ifQ=="

class WebViewController: UIViewController, WKNavigationDelegate {
    
    private var webView: WKWebView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configureWebView()
    }
    
    private func configureWebView() {
        let config = WKWebViewConfiguration()
        config.processPool = WKProcessPool()
        webView = WKWebView(frame: .zero, configuration: config)
        webView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(self.webView)
        
        // We pin the web view to the safe area because some pages break otherwise.
        NSLayoutConstraint.activate([
            view.safeAreaLayoutGuide.leftAnchor.constraint(equalTo: webView.leftAnchor),
            view.safeAreaLayoutGuide.rightAnchor.constraint(equalTo: webView.rightAnchor),
            view.safeAreaLayoutGuide.topAnchor.constraint(equalTo: webView.topAnchor),
            view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
        ])
        
        webView.navigationDelegate = self
        self.loadRequest()
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        
    }
    
    private func loadRequest() {
        DispatchQueue.main.async {
            let url = URL(string: url)!
            var request =  URLRequest(url: url)
            request.httpShouldHandleCookies = true
            self.webView.load(request)
        }
    }
    
    // Errors
    
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        showAlert(for: error)
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        showAlert(for: error)
    }
    
    private func showAlert(for error: Error) {
        let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(alert, animated: true, completion: nil)
    }
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        decisionHandler(.allow)
    }
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        
        guard let response = navigationResponse.response as? HTTPURLResponse,
              let url = navigationResponse.response.url else {
            decisionHandler(.cancel)
            return
        }
        
        if let headerFields = response.allHeaderFields as? [String: String] {
            let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url)
            print( "cookies", cookies)
            cookies.forEach { cookie in
                webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
            }
        }
        decisionHandler(.allow)
    }
}

在上面的代码中,htmlStringurl将从后端获得。从url获得下面的页面。

5n0oy7gb

5n0oy7gb1#

WKWebView提供了WKNavigationDelegate提供的不同回调,可以使用的是func webView(WKWebView, decidePolicyFor: WKNavigationResponse, decisionHandler: (WKNavigationResponsePolicy) -> Void).
每次返回响应时,都可以从头字段中获取cookie并将其保存到cookie存储中。解决方案如下:

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

  if let headerFields = response.allHeaderFields as? [String: String] {
    let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url)
    cookies.forEach { cookie in
      webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
    }
  }
  
  decisionHandler(.allow)
}

相关问题