小程序: webview 不支持打开 https://__birdge_loaded__/

一个由于 jsbridge 引起的 webview 无法打开的BUG
更新于: 2023-07-21 09:44:24

解决方案

在小程序环境,直接中止掉 bridge 中 iframe 的运行逻辑。

declare global {
  interface Window {
    WebViewJavascriptBridge: any;
    WVJBCallbacks: any;
  }
}

const isWxMiniprogram = () => {
  const ua = navigator.userAgent.toLowerCase();
  return ua.indexOf("miniprogram") > -1;
};

export default () => {
  return new Promise((resolve) => {
    
    // @aric.zheng(2023-07-13 09:04:35)
    // wx miniprogram should return null
    if (isWxMiniprogram()) return resolve(null);

    // android
    function onBridgeReady() {
      document.removeEventListener(
        "WebViewJavascriptBridgeReady",
        onBridgeReady
      );

      console.info(
        `<<Rhino>> current existEventListener window.WebViewJavascriptBridge ${window.WebViewJavascriptBridge}`
      );
      resolve(window.WebViewJavascriptBridge);
    }

    if (window.WebViewJavascriptBridge) {
      console.info(
        `<<Rhino>> current exist window.WebViewJavascriptBridge ${window.WebViewJavascriptBridge}`
      );
      return resolve(window.WebViewJavascriptBridge);
    } else {
      console.info(
        `<<Rhino>> current not exist window.WebViewJavascriptBridge ${window.WebViewJavascriptBridge}`
      );
      document.addEventListener(
        "WebViewJavascriptBridgeReady",
        onBridgeReady,
        false
      );
    }

    // ios
    if (window.WVJBCallbacks) {
      return window.WVJBCallbacks.push(resolve);
    }
    window.WVJBCallbacks = [resolve];

    // iframe
    const WVJBIframe = document.createElement("iframe");
    WVJBIframe.style.display = "none";
    WVJBIframe.src = "https://__bridge_loaded__";
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(() => document.documentElement.removeChild(WVJBIframe), 0);
  });
};

核心逻辑

一个实际项目中的代码截图。

参考