如何在WKWebView中重写urlRequest以添加跳转请求头?
解决WKWebView内部跳转丢失自定义请求头的问题
嘿,作为iOS、Swift和Xcode的新手,碰到这个请求头丢失的问题太正常了!其实这和Android里重写shouldOverrideUrlLoading的思路一致,咱们在iOS里用WKNavigationDelegate的代理方法就能搞定。
核心思路
WKWebView内部页面跳转时,默认会用不带自定义请求头的请求加载新页面。我们需要拦截导航请求,替换成带有自定义请求头的新请求,再取消原请求的加载。
具体步骤
- 让ViewController遵守
WKNavigationDelegate协议 - 给WKWebView设置
navigationDelegate代理 - 实现
decidePolicyForNavigationAction代理方法拦截请求
完整代码示例
首先修改你的ViewController类声明,添加协议:
class YourViewController: UIViewController, WKNavigationDelegate { // 你的WKWebView实例,比如通过IBOutlet关联 @IBOutlet weak var webView: WKWebView! // 假设你的常量定义如下 let BASE_URL = "https://your-target-url.com" let X_CLIENT_TYPE = "X-Client-Type" let MOBILE = "mobile" override func viewDidLoad() { super.viewDidLoad() // 必须设置导航代理,否则无法拦截请求 webView.navigationDelegate = self // 首次加载带请求头的页面 guard let url = URL(string: BASE_URL) else { return } var request = URLRequest(url: url) request.addValue(MOBILE, forHTTPHeaderField: X_CLIENT_TYPE) webView.load(request) } // 拦截导航请求,添加自定义请求头 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { // 只处理主框架的跳转请求,避免拦截图片、脚本等资源加载 guard navigationAction.targetFrame?.isMainFrame == true, let targetUrl = navigationAction.request.url else { // 非主框架请求直接允许加载 decisionHandler(.allow) return } // 创建带自定义请求头的新请求 var newRequest = URLRequest(url: targetUrl) newRequest.addValue(MOBILE, forHTTPHeaderField: X_CLIENT_TYPE) // 用新请求加载页面 webView.load(newRequest) // 取消原导航请求,避免重复加载 decisionHandler(.cancel) } }
关键细节说明
- 判断
targetFrame.isMainFrame:这一步是为了只拦截页面跳转的请求,而不是网页内部的资源(比如图片、CSS、JS)加载请求,否则会影响页面的正常渲染。 decisionHandler的调用:必须调用这个闭包来告知WKWebView如何处理请求,我们用.cancel取消原请求,因为已经通过自定义请求加载了目标页面。
这样设置后,不管是首次加载还是内部链接跳转,都会带上你需要的X-Client-Type请求头啦!
内容的提问来源于stack exchange,提问作者Rudi Wijaya
相关产品推荐
相关产品推荐

