为了向 AJAX 请求添加自定义标头,我使用了两个三个 hack 的组合。第一个在我的原生 Swift 代码和 javascript 之间提供了一个同步通信通道。第二个覆盖 XMLHttpRequest send()方法。第三个将覆盖注入到加载到我的 WKWebView 中的网页中。
因此,组合的工作方式如下:
而不是request.setValue("value", forHTTPHeaderField: "key"):
在视图控制器中:
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt headerName: String, defaultText _: String?, initiatedByFrame _: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
if headerName == "key" {
completionHandler("value")
} else {
completionHandler(nil)
}
}}
在 viewDidLoad 中:
let script =
"XMLHttpRequest.prototype.realSend = XMLHttpRequest.prototype.send;"
"XMLHttpRequest.prototype.send = function (body) {"
"let value = window.prompt('key');"
"this.setRequestHeader('key', value);"
"this.realSend(body)"
"};"
webView.configuration.userContentController.addUserScript(WKUserScript(source: script, injectionTime: .atDocumentEnd, forMainFrameOnly: true))
这是测试 HTML 文件:
<html>
<head>
<script>
function loadAjax() {
const xmlhttp = new XMLHttpRequest()
xmlhttp.onload = function() {
document.getElementById("load").innerHTML = this.responseText
}
xmlhttp.open("GET", "/ajax")
xmlhttp.send()
}
</script>
</head>
<body>
<button onClick="loadAjax()">Change Content</button> <br />
<pre id="load">load…</pre>
</body>
</html>
调用会/ajax
带来一个通用的回声,包括所有请求标头。这样我就知道任务完成了。