> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# H5 与 App 双向通信

## 业务需求：

前期在微信 H5 端与 iOS 和 Android 进行数据交互，借助的是封装&#x7684;**[WebViewJavascriptBridge](https://github.com/marcuswestin/WebViewJavascriptBridge)**&#x51FD;数与 iOS 进行数据交互，然而与 Android 的数据交互还是一依据将交互的事件函数挂载到 window 上，以便于 Android 端 app 获取事件函数。虽然这种做法可以实现最终的效果，因为 H5 活动页面在 iOS 端 app、Android 端 app 以及微信端 H5 三端使用，与此同时还要依据不同参数或者不同 ua 信息处理不同的事件，相对来说代码逻辑比较复杂、冗余，容易出错，为此就寻找一个可以多端公用的方法。

本次封装的 JS 与 APP 进行数据交互的方法解决了**iOS、Android、WeChat**三端共用的问题，代码逻辑结构清晰明了、便于后续逻辑的调整和优化。

## 设备信息判断

```javascript title="设备信息判断"
var u = navigator.userAgent;
// Android 终端
var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1;
// iOS 终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
var isWeChat = u.match(/MicroMessenger/gi) == "micromessenger";
// 或者
let ua = navigator.userAgent;
// Android 端
let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Linux") > -1;
// iOS 终端
let isiOS = /iPhone|mac|iPod|iPad/i.test(ua);
//WeChat 终端
let isWeChat = !!window.__wxjs_is_wkwebview;
```

:::tip 设备检测
通过 **navigator.userAgent** 获取设备信息，在依据不同设备的不同参数来区分当前设备所处的环境是 Android、iOS 还是 WeChat。
:::

## 设备共用方法

```javascript title="设备共用方法"
function connectWebViewJavascriptBridge(callback) {
    if (isAndroid) {
        if (window.WebViewJavascriptBridge) {
            callback(WebViewJavascriptBridge);
        } else {
            document.addEventListener(
                "WebViewJavascriptBridgeReady",
                function () {
                    callback(WebViewJavascriptBridge);
                },
                false
            );
        }
        return;
    }
    if (isiOS) {
        if (window.WebViewJavascriptBridge) {
            return callback(WebViewJavascriptBridge);
        }
        if (window.WVJBCallbacks) {
            return window.WVJBCallbacks.push(callback);
        }
        window.WVJBCallbacks = [callback];
        var WVJBIframe = document.createElement("iframe");
        WVJBIframe.style.display = "none";
        WVJBIframe.src = "https://__bridge_loaded__";
        document.documentElement.appendChild(WVJBIframe);
        setTimeout(function () {
            document.documentElement.removeChild(WVJBIframe);
        }, 0);
    }
}
// 调用注册方法
connectWebViewJavascriptBridge(function (bridge) {
    if (isAndroid) {
        bridge.init(function (message, responseCallback) {
            responseCallback(data);
        });
    }
});
```

## 设备事件交互

```javascript title="设备事件交互"
// 调用Android和iOS端方法，并接收返回数据回调js方法
window.WebViewJavascriptBridge.callHandler(
    "jsToAppFn",
    {
        orderInfo: data,
    },
    function (res) {
        window.console.log(res);
    }
);

// 提供js方法供Android和iOS端调用
window.WebViewJavascriptBridge.registerHandler(
    "appToJsFn",
    function (data, responseCallback) {
        // data 是 APP 传递过来的数据.
        // data数据两端协商好，若使用JSON字符串，js端需要转换JSON对象
        // responseCallback 是 JS 调用完毕之后传递给 APP 的数据
        responseCallback({
            key: "value",
        });
    }
);
```
