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

React Native WebView 首次进入报atrium://未知URL scheme错误

问题根因
  • 原生WebView组件首次挂载时存在执行时序差:原生层会优先完成实例创建、启动初始source指定URL的加载流程,之后才会将JS侧注册的导航类回调同步到原生代码层。
  • 当前加载的HTTPS目标页面,在页面DOM加载完成后会第一时间触发atrium://自定义scheme跳转请求,该请求发生在JS拦截回调同步到原生层之前,原生层因未接收到自定义scheme的拦截规则,会按默认未知scheme逻辑抛出UNKNOWN_URL_SCHEME错误。
  • 二次进入页面时,原生WebView实例已被路由栈缓存,JS侧的拦截回调早已完成同步注册,触发的自定义scheme请求会被正常拦截,因此不会出现报错。
  • 现有代码存在逻辑偏差:onNavigationStateChange回调无阻断页面加载的能力,仅用于同步导航状态信息,将拦截逻辑放在该回调中本身无法起到拦截作用;真正能阻断请求加载的只有onShouldStartLoadWithRequest回调。
修复方案
  • 拆分两个回调的职责,单独实现请求拦截逻辑,不要共用同一个处理函数:
// 仅负责请求拦截,明确对自定义scheme返回false阻断原生加载
const handleShouldStartLoadWithRequest = request => {
  const { url } = request;
  if (url.startsWith('atrium://')) {
    // 执行自定义scheme对应的业务逻辑
    return false;
  }
  return true;
}

// 仅负责同步导航状态信息,不做拦截处理
const handleWebViewNavigationStateChange = newNavState => {
  const { url } = newNavState;
  console.log("当前加载URL:", url)
}
  • 调整初始加载流程,规避首次加载的时序差问题:WebView首次挂载时先加载空白占位页,等原生实例完成初始化、所有回调同步注册完成后,再加载目标业务URL。
// 增加状态标记WebView是否完成初始化
const [isWebViewReady, setIsWebViewReady] = useState(false);

<WebView
  setSupportMultipleWindows={false}
  ref={webView}
  originWhitelist={['http://*', 'https://*', 'atrium://*']}
  // 首次挂载先加载空白页,就绪后再加载目标业务地址
  source={isWebViewReady ? { uri: route.params.url } : { html: '' }}
  style={{ flex: 1 }}
  javaScriptEnabled={true}
  onNavigationStateChange={handleWebViewNavigationStateChange}
  onShouldStartLoadWithRequest={handleShouldStartLoadWithRequest}
  // 收到首次加载启动事件时,标记组件已就绪
  onLoadStart={() => {
    if (!isWebViewReady) setIsWebViewReady(true)
  }}
/>
  • 补充原生层的scheme识别配置:安卓端需在对应承载WebView的Activity配置中,补充atrium:// scheme的识别规则;iOS端需在应用配置文件中补充对atrium scheme的查询权限,避免原生层未收到JS回调时直接抛出未知scheme错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 12:45:00