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

React Native WebView注入JavaScript:异步脚本执行问题求助

解决React Native WebView中异步JavaScript脚本执行问题

我明白你遇到的困扰了——第一个带setTimeout的脚本能正常把购物车数据通过postMessage传回原生,但第二个异步fetch脚本就是跑不起来。这主要是因为异步脚本的执行逻辑和数据传递方式需要调整,下面给你一步步的解决方案:

1. 修正异步脚本逻辑,主动传递结果

你原来的异步脚本用了顶层await,而且只是return结果,但WebView的JS环境里顶层await可能不被支持,更关键的是:异步操作完成后,结果不会自动传递给原生,必须主动调用window.ReactNativeWebView.postMessage把数据发回去。

修改后的脚本应该是这样的:

async function extractItems() {
  try {
    const responsePromise = await fetch('https://www2.hm.com/tr_tr/v1/carts', { credentials: 'include'});
    const response = await responsePromise.json();
    // 把解析后的结果发送给原生
    window.ReactNativeWebView.postMessage(JSON.stringify(response));
  } catch (error) {
    // 捕获并发送错误信息,方便调试
    window.ReactNativeWebView.postMessage(JSON.stringify({ error: error.message }));
  }
}
// 主动调用函数触发异步操作
extractItems();

2. 调整脚本注入时机,确保页面环境就绪

你之前用的injectedJavaScript是在页面开始加载时注入的,这时候可能页面的cookie还没准备好(比如用户还没完成登录会话),导致fetch请求拿不到正确的数据。更好的方式是在页面完全加载完成后,用injectJavaScript方法手动注入脚本:

修改你的WebView组件代码:

// 定义加载完成后的脚本注入逻辑
const onLoadWebUrl = () => {
  const asyncJsCode = `
    async function extractItems() {
      try {
        const responsePromise = await fetch('https://www2.hm.com/tr_tr/v1/carts', { credentials: 'include'});
        const response = await responsePromise.json();
        window.ReactNativeWebView.postMessage(JSON.stringify(response));
      } catch (error) {
        window.ReactNativeWebView.postMessage(JSON.stringify({ error: error.message }));
      }
    }
    extractItems();
  `;
  // 调用WebView的injectJavaScript方法执行脚本
  webViewRef.current?.injectJavaScript(asyncJsCode);
};

// 调整WebView组件配置
<WebView
  ref={webViewRef}
  source={{uri: webUrl}}
  onNavigationStateChange={webViewState => {
    // setWebUrl(webViewState?.url);
  }}
  javaScriptEnabled={true}
  domStorageEnabled={true}
  startInLoadingState={true}
  // 移除原来的injectedJavaScript属性
  onLoadEnd={() => onLoadWebUrl()}
  renderLoading={() => <Loading visible />}
  onError={() => webViewRef.current.reload()}
  onMessage={event => {
    console.log("onMessage event ==> ", event.nativeEvent.data);
    // 解析收到的消息
    const receivedData = JSON.parse(event.nativeEvent.data);
    if (receivedData.error) {
      console.error("提取购物车数据出错:", receivedData.error);
    } else {
      if (cartUrl !== '') {
        onMessage(event);
      }
    }
  }}
/>

3. 额外的排查点

  • 跨域与凭证问题:因为你是在hm.com的页面里fetch同域接口,所以跨域不是问题,但要确保用户已经登录(页面有有效的cookie),credentials: 'include'会正确携带cookie,这是获取购物车数据的前提。
  • WebView权限:你已经开启了javaScriptEnabled和domStorageEnabled,这两个是必须的配置,没问题。
  • 调试技巧:可以在onMessage里打印完整的event.nativeEvent.data,看看是收到了错误信息还是空数据,方便定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 00:39:05