You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

原生App WebView能否仅为宿主开放unsafe-eval,同时禁止其他内容使用?

关于CSP规则的疑问解答

首先明确:unsafe-eval是CSP针对全局JS执行上下文的控制规则,不支持针对特定调用源(比如原生端)单独加白名单,只要开启就会对所有页面内的JS执行生效,不符合你的安全需求。

无需放宽CSP的通信方案(推荐)

你完全不需要借助动态eval就能实现App到JS的运行时通信,核心思路是提前在页面加载阶段注入固定的通信桥接代码,原生端仅调用预定义的固定桥接方法即可,这类调用不会触发CSP的unsafe-eval限制。
具体实现步骤如下:

  • 页面加载阶段(你已经可以实现脚本注入的阶段)注入固定的桥接JS代码:
// 注入的全局桥接对象,固定代码无动态逻辑
window.AppCommunicationBridge = {
  // 存储业务方注册的消息处理回调
  messageHandler: null,
  // 业务层调用该方法注册消息回调
  registerHandler: function(handler) {
    this.messageHandler = handler
  },
  // 供原生端调用的固定接收方法
  receiveNativeMessage: function(messageStr) {
    if (typeof this.messageHandler === 'function') {
      try {
        const message = JSON.parse(messageStr)
        this.messageHandler(message)
      } catch (e) {
        console.error('Native message parse error', e)
      }
    }
  }
}
  • 原生端需要向JS发送消息时,直接调用上述预定义的固定方法即可:
    • iOS WKWebView:调用evaluateJavaScript执行的代码为固定格式:
      window.AppCommunicationBridge.receiveNativeMessage('<序列化后的消息JSON字符串>')
    • Android WebView:调用evaluateJavascript执行上述相同格式的代码即可,4.4以下系统可以用loadUrl("javascript:" + 上述代码)

注意:序列化消息时需要对JSON字符串中的单引号、反斜杠、换行符等特殊字符做转义,避免破坏JS字符串语法。

  • 如果需要实现带返回值的异步调用,可以在消息中携带唯一的requestId,JS处理完成后通过你已经实现的JS到原生桥(WKScriptMessageHandler/JavascriptInterface)将requestId和处理结果回传给原生端即可。
备选轻量方案(无需预先注入代码)

如果不想注入桥接代码,还可以通过浏览器原生事件实现通信:

  • 原生端修改当前页面的location.hash,将消息编码后放在hash中,JS监听hashchange事件即可拿到消息,hash修改不会触发页面重载,也没有CSP限制。
  • 原生端可以通过修改document.title传递短消息,JS监听DOMAttrModified或者轮询title变化获取消息,适合短消息场景。

内容的提问来源于stack exchange,提问作者jlew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:06:04