天天看點

APP内嵌H5頁面中JS和APP的互動解決方案(可傳參、可回調)

前言

項目的快速疊代過程中,APP中嵌入H5頁面已是很常見的做法。

一定會有APP和JS的互動場景,例如JS喚起APP并攜帶參數...

互動方式

方法一:app端攔截和h5端約定好的特定url

// 不帶參
window.location.href = 'https://xxx.focus.cn/backtoapp'
// 帶參
window.location.href = 'https://xxx.focus.cn/backtoapp?data=xxx'           

複制

存在的問題:

  • 有些方案為了規避 url 長度隐患的缺陷,在 iOS 上采用了使用 Ajax 發送同域請求的方式,并将參數放到 head 或 body 裡。這樣,雖然規避了 url 長度的隐患,但是 WKWebView 并不支援這樣的方式。
  • 為什麼選擇 iframe.src 不選擇 locaiton.href ?因為如果通過 location.href 連續調用 Native,很容易丢失一些調用。
  • 連續多次修改window.location.href的值,在Native層隻能接收到最後一次請求,前面的請求都會被忽略掉。
  • 隻解決了js調用原生的問題。至于調用的結果和調用完之後要進行一些頁面的回調,通過這個攔截url的方式是沒辦法進行的。

方法二:使用WebViewJavascriptBridge

本質上,它是通過

webview

的代理攔截

scheme

,然後注入相應的

JS

方法三:使用

webkit MessageHandler

原理同

WebViewJavascriptBridge

本庫

本庫主要使用

WebViewJavascriptBridge

webkit MessageHandler

進行封裝。

使用

WebViewJavascriptBridge

webkit MessageHandler

APP端

  • ios封裝
  • android封裝

H5端

原理: H5頁面 <-->

Native App

執行被調用

Native

代碼傳回調用結果(H5頁面執行被調用JavaScript代碼并傳回調用結果)

封裝 bridge.js。

index.html中使用:

<button id="btn">模拟調用登入帶參數和回調</button>           

複制

index.js中使用:

require('/path/to/bridge.js');
// 需要和用戶端同學提前約定好互相調用的方法名及參數及回調,包裹所需要用到的函數
HFWVBridge.wrapNativeFn(['login']);
document.getElementById('btn').onclick = function() {
    // Android端如果使用 messageHandlers 方式,HFWVBridge 即可;
    // 如果沒有而是使用 WebViewJavascriptBridge ,則使用 window.WebViewJavascriptBridge.callHandler
    if (isFocusAppIOS()) {
        HFWVBridge.runNative('login', {
            name: '搜狐網友'
        }, function() {
            alert('歡迎來到搜狐');
        })
    } else {
        /**
         *
         * @desc 方式一:發送消息給app
         * @param {Any} 發送的消息
         * @param {Function} 發送消息給app後的的回調,且能拿到app傳回的資料
         */
        var data = {id: 1, content: "這是一個圖檔 <img src=\"a.png\"/> test\r\nhahaha"};
        window.WebViewJavascriptBridge.send(
            data
            , function(responseData) {
                document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData
            }
        );

        /**
         *
         * @desc 方式二:調用app的方法
         * @param {String} 與用戶端事先約定好的調用方法名
         * @param {Object} 調用app方法的傳參
         * @param {Function} 調用app方法的的回調,且能拿到app傳回的資料
         */
        window.WebViewJavascriptBridge.callHandler(
            'submitFromWeb'
            , {'param': '中文測試'}
            , function(responseData) {
                document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
            }
        );
    }    
};
HFWVBridge.add('hideBtn',function(){
    document.getElementById('btn').style.display = 'none';
});           

複制

優點及缺點

優點

  • 移動端不需要再攔截跳轉連結,寫死減少。
  • 支援雙向回調,支援異步回調。
  • 安全性高。

缺點

  • JS、IOS、Android三端代碼初始化較多,也比較複雜。需要一個全端大佬,出現問題能及時修複。

引用

  • WebViewJavascriptBridge
  • WebViewJavascriptBridge的詳細使用 -簡書
  • iOS下JS與OC互相調用(三)--MessageHandler -簡書
  • js 向 Native 一句話傳值并反射出 Swift 對象執行指定函數