使用WebView evaluateJavascript设置全局JS JSON对象失败如何解决?
问题根因
- 语法转义错误:现有Kotlin代码拼合JS语句时,嵌套双引号的转义逻辑错误,最终传入WebView执行的代码为
globalJSVariable = "{"someKey":"someValue"}";,外层双引号在{前已经闭合,后续的冒号会直接触发JS语法解析错误,对应你看到的Uncaught SyntaxError: Unexpected token ':'报错。 - 注入时机错误:
onPageStarted阶段页面JS上下文未完成初始化,此时注入的变量会被后续页面加载逻辑覆盖,甚至直接注入失败。 - 错误方案逻辑缺陷:
evaluateJavascript仅接收纯JS代码片段,不需要包裹<script>标签,添加标签会直接触发语法错误,因此连整数变量都无法设置成功。evaluateJavascript不会自动解码Base64内容,编码后的字符串不属于合法JS代码,执行无任何效果。- Moshi序列化无效果是因为后续拼合JS代码时仍存在转义错误,和序列化工具本身无关。
解决方案
首先将注入逻辑从onPageStarted迁移到onPageFinished回调,确保页面JS上下文初始化完成后再执行注入,再根据使用场景选择对应写法:
固定结构JSON对象写法
如果注入的JSON结构固定,直接用Kotlin原始字符串拼合合法JS对象字面量即可:
class WebViewClientImpl : WebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) setGlobalJSVariable(view) } private fun setGlobalJSVariable(view: WebView?) { // 三个引号声明的原始字符串无需手动转义双引号,直接写合法JS对象 val jsCode = """javascript: globalJSVariable = {"someKey":"someValue"};""" view?.evaluateJavascript(jsCode, null) } }
动态内容JSON通用写法
如果注入的JSON内容为动态生成,先通过JSON序列化工具得到合法JSON字符串,再通过JSON.parse转换为JS对象,完全规避转义冲突:
private fun setGlobalJSVariable(view: WebView?, dynamicData: Any) { // 示例使用Moshi序列化,可替换为任意JSON序列化工具 val moshi = Moshi.Builder().build() val jsonAdapter = moshi.adapter(dynamicData.javaClass) val validJsonStr = jsonAdapter.toJson(dynamicData) // JSON字符串放入单引号中,完全避免双引号嵌套问题 val jsCode = """javascript: globalJSVariable = JSON.parse('$validJsonStr');""" view?.evaluateJavascript(jsCode, null) }
内容的提问来源于stack exchange,提问作者ToeKnee
相关产品推荐
相关产品推荐

