如何在swift中为iOS添加全球范围的HTTP标头

func webView(webView: WKWebView!, decidePolicyForNavigationAction navigationAction: WKNavigationAction!, decisionHandler: ((WKNavigationActionPolicy) -> Void)!) { var request = NSMutableURLRequest(URL: navigationAction.request.URL) request.setValue("value", forHTTPHeaderField: "key") decisionHandler(.Allow) } 

在上面的代码中,我想为请求添加一个头。 我试图做navigationAction.request.setValue("IOS", forKey: "DEVICE_APP")但它不起作用。

请以任何方式帮助我。

AFAIK可悲的是你不能用WKWebView做到这WKWebView

它绝对不能在webView:decidePolicyForNavigationAction:decisionHandler:因为navigationAction.request是只读的,而且是不可更改的NSURLRequest实例,您不能更改。

如果我理解正确, WKWebView将运行在单独的内容和networking进程中的沙盒,至less在iOS上,无法拦截或更改networking请求。

你可以做到这一点,如果你退后一步到UIWebView

有很多不同的方法来做到这一点,我发现最简单的解决scheme是inheritanceWKWebView并重载loadRequest方法。 像这样的东西:

 class CustomWebView: WKWebView { override func loadRequest(request: NSURLRequest) -> WKNavigation? { guard let mutableRequest = request.mutableCopy() as? NSMutableURLRequest else { return super.loadRequest(request) } mutableRequest.setValue("custom value", forHTTPHeaderField: "custom field") return super.loadRequest(mutableRequest) } } 

然后简单地使用CustomWebView类,就好像它是一个WKWebView。

编辑注意 :这将只适用于@Stefan Arentz指出的第一个请求。

:一些字段不能被覆盖,不会被改变。 我还没有做过彻底的testing,但是我知道, User-Agent字段不能被覆盖,除非你做了一个特定的黑客( 检查这里的答案 )

有一些限制,但你可以做到。 拦截委托函数webView:decidePolicyFornavigationResponse:decisionHandler:的响应webView:decidePolicyFornavigationResponse:decisionHandler:如果url更改通过传递decisionHandler(.cancel)取消它,并用新的URLRequest重新加载webview, decisionHandler(.cancel)会设置自定义标题和拦截的url。 通过这种方式,每次URL改变(例如,用户点击链接),您取消该请求,并创build一个新的自定义标题。

 import UIKit import WebKit class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView? var loadUrl = URL(string: "https://www.google.com/")! override func viewDidLoad() { super.viewDidLoad() webView = WKWebView(frame: CGRect.zero) webView!.navigationDelegate = self view.addSubview(webView!) webView!.translatesAutoresizingMaskIntoConstraints = false webView!.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true webView!.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true webView!.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true webView!.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true // Load first request with initial url loadWebPage(url: loadUrl) } func loadWebPage(url: URL) { var customRequest = URLRequest(url: url) customRequest.setValue("some value", forHTTPHeaderField: "custom header key") webView!.load(customRequest) } // MARK: - WKNavigationDelegate func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { guard let url = (navigationResponse.response as! HTTPURLResponse).url else { decisionHandler(.cancel) return } // If url changes, cancel current request which has no custom headers appended and load a new request with that url with custom headers if url != loadUrl { loadUrl = url decisionHandler(.cancel) loadWebPage(url: url) } else { decisionHandler(.allow) } } } 

下面是你如何做:策略是让你的WKNavigationDelegate取消请求,修改它的可变副本,并重新启动它。 if-else用于允许请求继续进行,如果它已经有了所需的头部; 否则,你将在无尽的加载/决定策略循环结束。

不知道发生了什么,但是如果您在每个请求上设置标题,会发生奇怪的事情,所以为了获得最佳结果,只能将请求头设置为您关心的域。

这里的例子为header.domain.com设置了一个头域的请求,并允许所有其他请求没有头:

 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSURL * actionURL = navigationAction.request.URL; if ([actionURL.host isEqualToString:@"header.domain.com"]) { NSString * headerField = @"x-header-field"; NSString * headerValue = @"value"; if ([[navigationAction.request valueForHTTPHeaderField:headerField] isEqualToString:headerValue]) { decisionHandler(WKNavigationActionPolicyAllow); } else { NSMutableURLRequest * newRequest = [navigationAction.request mutableCopy]; [newRequest setValue:headerValue forHTTPHeaderField:headerField]; decisionHandler(WKNavigationActionPolicyCancel); [webView loadRequest:newRequest]; } } else { decisionHandler(WKNavigationActionPolicyAllow); } } 
Interesting Posts