向 WKWebView 中的所有传出请求添加请求标头

问题描述 投票:0回答:2

TL;DR:我有一个带有 WKWebView 的 iOS (Swift) 项目。我想向此 WKWebView 中的所有传出请求(html、图像、脚本、样式表等)添加请求标头。我不知道该怎么做。

背景:
我有一个 Swift iOS 应用程序,它使用 WKWebView 来呈现它的 html 视图。这些视图托管在我们的服务器上,该服务器分为生产环境和临时环境。我已使用 Akamai 设置了暂存环境,以便所有传入请求都必须传递请求标头才能接受请求。

问题:
目前,我创建了 WKWebView 的子类,它重写了 loadRequest 方法,如下所示:

override func loadRequest(request: NSURLRequest) -> WKNavigation? {
    guard let mutableRequest = request.mutableCopy() as? NSMutableURLRequest else {
        return super.loadRequest(request)
    }

    if let url = request.URL, host = url.host {
        if (host == "staging.example.com") {
            mutableRequest.setValue("secret-value", forHTTPHeaderField: "secret-header")
        }
    }


    return super.loadRequest(mutableRequest)
}

这捕获了初始 html 请求,它按预期工作。但是,由于该页面又从同一服务器加载图像、样式表和脚本,因此这些不会通过 loadRequest 方法并被拒绝,因为它们的请求缺少此必需的请求标头。

要求:
它必须与 iOS 8+ 上的 WKWebView 配合使用。

ios swift header request wkwebview
2个回答
4
投票

当前的 API 是不可能的 - 您无法处理

WKWebView
发出的所有请求。您可以使用
UIWebView
+ 自定义 url 协议
WKWebView
不支持)并将标头添加到特定服务器的所有请求中作为替代方案。


0
投票

对于将来遇到此问题的任何人来说,这是可能的:

 extension SomeObjectThatIsADelegate: WKNavigationDelegate {

 // Intercept all requests and insert the necessary headers
 func webView(
     _ webView: WKWebView,
     decidePolicyFor navigationAction: WKNavigationAction,
     decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
 ) {
     let headerName = "Header-Name"
     let expectedHeaderValue = "header_value"

     let headers = navigationAction.request.allHTTPHeaderFields ?? [:]
     let isMatched = headers.contains { $0.key == headerName && $0.value == expectedHeaderValue }

     if isMatched {
         decisionHandler(.allow)
     } else {
         // Cancel and re-run the request with our header inserted
         decisionHandler(.cancel)

         var requestWithDeviceType = navigationAction.request
         var headers = requestWithDeviceType.allHTTPHeaderFields ?? [:]
         headers[headerName] = expectedHeaderValue
         requestWithDeviceType.allHTTPHeaderFields = headers
         webView.load(requestWithDeviceType)
     }
 }
© www.soinside.com 2019 - 2024. All rights reserved.