func webView(webView: WKWebView!, decidePolicyForNavigationAction navigationAction: WKNavigationAction!, decisionHandler: ((WKNavigationActionPolicy) -> Void)!) {
var request = NSMutableURLRequest(URL: navigationAction.request.URL)
request.setValue("value", forHTTPHeaderField: "key")
decisionHandler(.Allow)
}
在上面的代码中,我想给请求添加一个header。我试过做navigationAction.request.setValue("IOS", forKey: "DEVICE_APP")
,但它不工作。
无论如何请帮帮我。
9条答案
按热度按时间j0pj023g1#
很遗憾,你不能用
WKWebView
做到这一点。它在
webView:decidePolicyForNavigationAction:decisionHandler:
中肯定不起作用,因为navigationAction.request
是只读的,并且是不可更改的NSURLRequest
示例。如果我理解正确的话,
WKWebView
在一个单独的内容和网络进程中运行沙箱,至少在iOS上,没有办法拦截或更改它的网络请求。如果您返回到
UIWebView
,就可以做到这一点。vbkedwbf2#
有很多不同的方法可以做到这一点,我发现最简单的解决方案是子类化WKWebView并覆盖loadRequest方法。大概是这样的:
然后简单地使用CustomWebView类,就像它是一个WKWebView一样。
编辑注解:正如@Stefan Arentz指出的那样,这只适用于第一个请求。
注意:某些字段不能被覆盖,也不会被更改。我还没有做过彻底的测试,但我知道,
User-Agent
字段不能被覆盖,除非你做一个特定的黑客(check here for an answer to that)htzpubme3#
我已经修改了Au Ris的答案,使用
NavigationAction
而不是NavigationResponse
,就像jonny建议的那样。此外,这修复了随后调用相同URL的情况,并且您不必再跟踪当前URL。这只适用于GET请求,但如果必要的话,肯定可以适用于其他请求类型。ezykj2lf4#
有一些限制,但你可以做到。拦截委托函数
webView:decidePolicyFornavigationResponse:decisionHandler:
中的响应,如果url改变,通过传递decisionHandler(.cancel)
取消它,并使用新的URLRequest
重新加载webview,设置自定义头和拦截的url。每次URL更改时(例如,用户点击链接),则取消该请求并创建一个带有自定义标题的新请求。jtoj6r0c5#
为了向AJAX请求添加自定义头,我使用了两个三个技巧的组合。first在我的原生Swift代码和JavaScript之间提供了一个同步通信通道。second覆盖XMLHttpRequestsend()方法。third将覆盖注入到加载到我的WKWebView中的网页中。
所以,这个组合是这样的:
而不是request.setValue(“value”,forHTTPHeaderField:“key”):
对
/ajax
的调用会带来一个通用的echo,包括所有的请求头。这样我就知道任务完成了。uinbv5nw6#
你应该这么做:策略是让WKNavigationDelegate取消请求,修改它的可变副本并重新启动它。if-else用于在请求已经具有所需的报头时允许请求继续;否则,您将陷入无休止的load / decidePolicy循环。
不知道是怎么回事,但是如果你在每个请求上都设置了header,就会发生奇怪的事情,所以为了获得最好的结果,只在你关心的域的请求上设置header。
这里的例子为请求header.domain.com设置了一个header字段,并允许所有其他没有header的请求:
smdnsysy7#
kmpatx3s8#
我的解决方案是复制请求并添加标头,然后再次加载它
ohtdti5x9#
上面提到的解决方案似乎可以在iOS 14上工作,但在iOS < 14上,POST请求Body总是null,导致服务器端拒绝请求。事实证明,这是WKWebView和WebKit中的一个已知错误,导致navigationLink.Request.Body始终为nil!!非常令人沮丧和愚蠢的错误,从苹果迫使UIWebView迁移到不稳定的WKWebView!
无论如何,解决方案是你应该(在取消请求之前),通过运行JavaScript函数获取POST主体,然后将结果分配回navigationAction.Request(如果navigationAction.Request.Body为null),然后取消操作,并使用更新的navigationAction.Request再次请求:
解决方案在Xamarin中,但原生iOS非常接近。