WKWebView 得到 Javascript 个错误
WKWebView get Javascript Errors
有没有办法从 Webview 中获取 Javascript 错误?我的意思是以下错误和可能的警告?
我运行JS代码扩展如下
```
extension WKWebView {
func evaluateJavaScriptWithReturn(_ javaScriptString: String) -> String? {
var finished = false
var jsValue: String?
evaluateJavaScript(javaScriptString) { (result, error) in
if error == nil {
if result != nil {
jsValue = result as? String
}
} else {
jsValue = nil
}
finished = true
}
while !finished {
RunLoop.current.run(mode: .defaultRunLoopMode, before: Date.distantFuture)
}
return jsValue
}
}
```
但是 error
不是我要找的!
有什么方法可以让我的应用程序出现上述错误?
非常感谢!
试试下面的方法。
首先,注入JS代码捕获html内容中的错误:
window.onerror = function(error) {
alert(error); // Fire when errors occur. Just a test, not always do this.
};
其次,显示WKWebView委托方法中的错误:
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: "alert", message: message, preferredStyle: UIAlertControllerStyle.alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil))
self.present(alertController, animated: true, completion: nil)
print("An error from web view: \(message)")
}
记得设置委托:
webView.uiDelegate = self
如果你想避免警报,另一种方法是使用 decidePolicyForNavigationAction
方法来接收 JS 的回调,如 window.open("error://message","_self")
我发现的最佳解决方案是使用 Safari 的 Web Inspector。找到说明 here。
我将 运行 保存到 Script error.
条带有 Yun CHEN 解决方案(很棒)的消息中,但没有任何可操作的内容。
在 JavaScript 中,挂钩 window onerror 事件以回调您的脚本消息处理程序:
window.onerror = function (msg, url, line) {
window.webkit.messageHandlers.mylog.postMessage("JS: ERROR:" + msg + " @" + url + ":" + line);
};
您可能只会收到 "Script error." 条消息,这是权限问题。 (documentation) 根据您的设置,可以通过在首选项中添加权限来解决此问题。
Swift:
webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
为了处理错误,我们将向加载到我们页面的 HTML 添加一些 JavaScript,以通知我们的本机代码有关错误。
首先,您需要使用脚本消息处理程序设置 Web 视图:
let controller = WKUserContentController()
controller.add(self, name: "error")
let configuration = WKWebViewConfiguration()
configuration.userContentController = controller
let webView = WKWebView(frame: .zero, configuration: configuration)
我在本地创建完整的 HTML 文档并注入以下 JavaScript:
window.onerror = (msg, url, line, column, error) => {
const message = {
message: msg,
url: url,
line: line,
column: column,
error: JSON.stringify(error)
}
if (window.webkit) {
window.webkit.messageHandlers.error.postMessage(message);
} else {
console.log("Error:", message);
}
};
(我有检查和记录,因为我有时 运行 在浏览器中生成 JavaScript。)你也可以使用 WKUserContentController
添加一个 WKUserScript
如果你想将它注入 HTML 你不能完全控制。
接下来,当您将字符串加载到 Web 视图中时,请务必使用 localhost
作为基础 URL。如果你不这样做,你所有的错误都将是 "Script error."
.
webView.loadHTMLString(html, baseURL: URL(string: "http://localhost/")!)
现在定义你的 WKScriptMessageHandler
:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
switch message.name {
case "error":
// You should actually handle the error :)
let error = (message.body as? [String: Any])?["message"] as? String ?? "unknown"
assertionFailure("JavaScript error: \(error)")
default:
assertionFailure("Received invalid message: \(message.name)")
}
}
对于添加到 WKUserContentController
的其他消息,您可以将其他情况添加到 switch 语句中。
有没有办法从 Webview 中获取 Javascript 错误?我的意思是以下错误和可能的警告?
我运行JS代码扩展如下
```
extension WKWebView {
func evaluateJavaScriptWithReturn(_ javaScriptString: String) -> String? {
var finished = false
var jsValue: String?
evaluateJavaScript(javaScriptString) { (result, error) in
if error == nil {
if result != nil {
jsValue = result as? String
}
} else {
jsValue = nil
}
finished = true
}
while !finished {
RunLoop.current.run(mode: .defaultRunLoopMode, before: Date.distantFuture)
}
return jsValue
}
}
```
但是 error
不是我要找的!
有什么方法可以让我的应用程序出现上述错误?
非常感谢!
试试下面的方法。
首先,注入JS代码捕获html内容中的错误:
window.onerror = function(error) {
alert(error); // Fire when errors occur. Just a test, not always do this.
};
其次,显示WKWebView委托方法中的错误:
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: "alert", message: message, preferredStyle: UIAlertControllerStyle.alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil))
self.present(alertController, animated: true, completion: nil)
print("An error from web view: \(message)")
}
记得设置委托:
webView.uiDelegate = self
如果你想避免警报,另一种方法是使用 decidePolicyForNavigationAction
方法来接收 JS 的回调,如 window.open("error://message","_self")
我发现的最佳解决方案是使用 Safari 的 Web Inspector。找到说明 here。
我将 运行 保存到 Script error.
条带有 Yun CHEN 解决方案(很棒)的消息中,但没有任何可操作的内容。
在 JavaScript 中,挂钩 window onerror 事件以回调您的脚本消息处理程序:
window.onerror = function (msg, url, line) {
window.webkit.messageHandlers.mylog.postMessage("JS: ERROR:" + msg + " @" + url + ":" + line);
};
您可能只会收到 "Script error." 条消息,这是权限问题。 (documentation) 根据您的设置,可以通过在首选项中添加权限来解决此问题。 Swift:
webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
为了处理错误,我们将向加载到我们页面的 HTML 添加一些 JavaScript,以通知我们的本机代码有关错误。
首先,您需要使用脚本消息处理程序设置 Web 视图:
let controller = WKUserContentController()
controller.add(self, name: "error")
let configuration = WKWebViewConfiguration()
configuration.userContentController = controller
let webView = WKWebView(frame: .zero, configuration: configuration)
我在本地创建完整的 HTML 文档并注入以下 JavaScript:
window.onerror = (msg, url, line, column, error) => {
const message = {
message: msg,
url: url,
line: line,
column: column,
error: JSON.stringify(error)
}
if (window.webkit) {
window.webkit.messageHandlers.error.postMessage(message);
} else {
console.log("Error:", message);
}
};
(我有检查和记录,因为我有时 运行 在浏览器中生成 JavaScript。)你也可以使用 WKUserContentController
添加一个 WKUserScript
如果你想将它注入 HTML 你不能完全控制。
接下来,当您将字符串加载到 Web 视图中时,请务必使用 localhost
作为基础 URL。如果你不这样做,你所有的错误都将是 "Script error."
.
webView.loadHTMLString(html, baseURL: URL(string: "http://localhost/")!)
现在定义你的 WKScriptMessageHandler
:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
switch message.name {
case "error":
// You should actually handle the error :)
let error = (message.body as? [String: Any])?["message"] as? String ?? "unknown"
assertionFailure("JavaScript error: \(error)")
default:
assertionFailure("Received invalid message: \(message.name)")
}
}
对于添加到 WKUserContentController
的其他消息,您可以将其他情况添加到 switch 语句中。