san*_*dip 16 http request-headers ios swift wkwebview
func webView(webView: WKWebView!, decidePolicyForNavigationAction navigationAction: WKNavigationAction!, decisionHandler: ((WKNavigationActionPolicy) -> Void)!) {
var request = NSMutableURLRequest(URL: navigationAction.request.URL)
request.setValue("value", forHTTPHeaderField: "key")
decisionHandler(.Allow)
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我想为请求添加一个标头.我试过,navigationAction.request.setValue("IOS", forKey: "DEVICE_APP")但它不起作用.
请以任何方式帮助我.
Ste*_*ntz 19
很遗憾AFAIK你不能这样做WKWebView.
它肯定不起作用,webView:decidePolicyForNavigationAction:decisionHandler:因为它navigationAction.request是只读的和不可变的NSURLRequest实例,你无法改变.
如果我理解正确,请WKWebView在单独的内容和网络流程中运行沙箱,至少在iOS上,无法拦截或更改其网络请求.
如果你退一步,你可以这样做UIWebView.
有很多不同的方法,我发现最简单的解决方案是子类WKWebView并覆盖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)
}
}
Run Code Online (Sandbox Code Playgroud)
然后简单地使用CustomWebView类,就像它是WKWebView一样.
编辑注意:这只适用于@Stefan Arentz指出的第一个请求.
注意:某些字段无法覆盖且不会更改.我没有做过彻底的测试,但我知道User-Agent除非你做一个特定的黑客攻击,否则不能覆盖该字段(请点击此处查看答案)
有一些限制,但是您可以做到。截获委托函数中的响应webView:decidePolicyFornavigationResponse:decisionHandler:,如果url更改,则通过传递decisionHandler(.cancel)并用新的webview重新加载,以URLRequest设置自定义标头和截获的url来取消响应。这样,每次更改网址(例如,用户点击链接),您便会取消该请求并使用自定义标头创建一个新请求。
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经修改了Au Ris答案,以NavigationAction代替NavigationResponsejonny建议使用。此外,这可以解决以下情况:随后将调用相同的URL,而您不必再跟踪当前的URL。这仅适用于GET请求,但如果需要,肯定可以适用于其他请求类型。
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: CGRect.zero)
webView!.navigationDelegate = self
view.addSubview(webView!)
// [...] set constraints and stuff
// Load first request with initial url
loadWebPage(url: "https://my.url")
}
func loadWebPage(url: URL) {
var customRequest = URLRequest(url: url)
customRequest.setValue("true", forHTTPHeaderField: "x-custom-header")
webView!.load(customRequest)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping
(WKNavigationActionPolicy) -> Void) {
if navigationAction.request.httpMethod != "GET" || navigationAction.request.value(forHTTPHeaderField: "x-custom-header") != nil {
// not a GET or already a custom request - continue
decisionHandler(.allow)
return
}
decisionHandler(.cancel)
loadWebPage(url: navigationAction.request.url!)
}
Run Code Online (Sandbox Code Playgroud)
}
| 归档时间: |
|
| 查看次数: |
21758 次 |
| 最近记录: |