h5與App原生互動方案
目前主流的技術方案:
1.在iOS7以前,在UIWebView中實現一些代理方法攔截帶有約定好的protocol的Url,從Url上獲取get方式的引數傳遞,對映成本地原生方法,如下:-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *urlString = request.URL .absoluteString;
if ([urlString rangeOfString:@"js-call://"].location != NSNotFound) {
NSString * host = [self sliceHost:urlString];
NSDictionary * params = [self sliceParams:urlString];
if ([host isEqualToString:@"openOrderDetail"]) {
[self openOrderDetail:params];
}
return NO;
}
return YES;
}
這僅僅解決了js呼叫原生方法的問題,至於呼叫的結果與呼叫完之後要進行一些頁面的回撥,在這個攔截的過程中根本沒有辦法進行,不過有一些蹩腳的補償措施,如下:
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
self.orderDetailCallBackFuncName = [webView stringByEvaluatingJavaScriptFromString:@"orderCallbackfuncName()"];
}
會在頁面載入完畢後主動去取頁面上設定的回撥方法的名稱,然後在原生方法中處理完邏輯再進行回撥。
-(void )OpenOrderDetail:(NSDictionary *)params{
//do someting
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@()",self.orderDetailCallBackFuncName ]];
}
2.iOS7以後,大家都使用JavaScriptCore這個官方的WebKit 的 JavaScript 引擎,實現oc與JavaScript的語言穿梭。
-(void)configJsCallBack{
WeakSelf;
self.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.jsContext.exceptionHandler = ^(JSContext * con,JSValue * exception){
NSLog(@"JS Error:%@",exception);
};
Coordinator * coordinator = [[Coordinator alloc]init];
self.jsContext[@"mobileCoordinator"] = coordinator;
self.jsContext[@"console"] = coordinator;
}
不太瞭解JavaScriptCore的同學可以自己查閱一下官方文件或者學習資料。這裡我們使用一些技巧,將所有的App開放給js的方法都由一個叫Coordinator的排程器來排程,而這個排程器實現了JSExport協議:
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
@protocol CoordinatorExport <JSExport>
-(void)log:(NSString *)msg;
-(BOOL)callNativeModule:(NSString *)url;
/*
js呼叫原生分享
shareOpinion為json物件
{
"type":"share",
"title":"share title",
"content":"share content",
"imgUrl":"",
"clickUrl":""
}
其中型別type有以下幾種:
share(只有朋友圈和微信好友),doubleShare(包含所有分享渠道),allShare(分享全部渠道)
*/
JSExportAs(showShareMenu, -(BOOL)showShareMenu:(NSString *)url opinion:(NSString *)opinion);
@end
@interface Coordinator : NSObject< CoordinatorExport >
@property(nonatomic,copy)BOOL (^openShareCallBack)(NSDictionary * opinion);
@end
上面的做法就是我們會在合適的實際向JavaScript的執行的環境中注入一個叫做mobileCoordinator的物件,這個物件會注入到JavaScript環境中的window物件上,全域性可用。為什麼要封裝到一個物件上,是因為js沒有名稱空間的概念並且有變數提升向上查詢,會引起命名衝突,所以我們把對外暴露的方法都進行一個物件封裝。還有一個好處就是JavaScript的開發者與app的開發者都會像編寫各自語言的程式碼一樣書寫程式碼,沒有語法損失,js同步呼叫原生方法,原生實現的時候具備返回值,js的呼叫者就可以獲取返回值,如果是非同步回撥,那可以對外暴露方法的時候提供一個callback的入參,在非同步完成後進行回撥。3.其他方案例如JavaScriptBridge等與第二種方案類似。
方案比較:
方案1的流程如下:互動方式為單向
H5呼叫Native:
H5頁面 —>發起Url Redirect(Url上攜帶帶有動作語義的引數)->Native App->攔截Url Redirect->解析動作語義引數->呼叫相關Native程式碼
Native呼叫H5頁面:
Native App—>獲取頁面上預留引數和解析動作語義引數->呼叫相關JavaScript程式碼
這樣使得一個簡單的方法呼叫變得非常割裂,而且雙端維護成本非常高,不易debug。方案2的流程如下:
互動為雙向:
H5頁面(Native App)<->呼叫Native程式碼(呼叫JavaScript程式碼)<->Native App執行被呼叫Native程式碼返回呼叫結果(H5頁面執行被呼叫JavaScript程式碼並返回呼叫結果)
方案2優勢比較明顯,一般會採用第二種。
實現細節
細節上有一些需要注意的東西:1.oc方法是帶有引數標籤的,js的方法並沒有,注意使用JSExportAs這個巨集來將oc原生語言轉換為js語法風格的程式碼。
2.注意獲取jscontext上下文並注入方法與物件的時機,這取決於H5頁面上的js引用時機,如果H5頁面上使用require來進行順序引用,就不會出現問題,如果與原生互動的js的程式碼載入與原生注入的注入順序混亂,則呼叫不到原生暴露的方法會引起js執行異常。建議結合攔截url的方式讓H5決定何時注入,或者是前端工程師梳理規範,在H5引用js的時候做順序控制。
防止注入與釣魚
其實這個不太算是技術方案,不過可以提一下。有時候手機在危險的網路環境中比方說連結在不安全的路由器中,DNS進行惡意中轉到釣魚網站上,如果頁面呼叫已知的原生暴露出來的方法,同步資料或者是呼叫關鍵業務,就會有注入攻擊的風險。一般需要做的是,H5在呼叫app原生關鍵業務的時候,需要在呼叫原生方法的時候傳入票據,原生通過服務端的認證中心驗證票據,通過才可以處理頁面呼叫請求,在同步資料與狀態的時候,比方說將app中的使用者登入狀態同步到H5頁面上,一般app會同步cookie,不過這種方式維護成本較高。對於同步狀態與資料,app應該使用業務票據來傳遞給H5,H5通過票據中心置換出真正的使用者狀態或者是關鍵業務資料。更高級別的方案還有H5與App臨時握手等。H5在WebView中的Debug
這個是一個比較噁心的事情,不過我們可以替換js的window物件上的console物件,將log函式轉接到原生,再通過一些其他方式進行輸出,JavaScriptCore中提供了exceptionHandlercontext.exceptionHandler = ^(JSContext *context, JSValue *exception) { NSLog(@"JS Error: %@", exception);};
下一篇文章將會介紹一下用websocket協議,將app中的WebView的除錯資訊輸出到指定IP的電腦上,方便開發除錯,這樣就能減少溝通與配合聯調,提高開發效率。相關推薦
h5與App原生互動方案
方便測試階段,H5嵌入到App當中,開發人員方便除錯與Debug。 目前主流的技術方案: 1.在iOS7以前,在UIWebView中實現一些代理方法攔截帶有約定好的protocol的Url,從Url上獲取get方式的引數傳遞,對映成本地原生方法,如下: -(BOOL)webView:(UIWebView *)
記一次利用vue.js完成的h5與app的互動
嘮叨:最近接收一個用vue寫的專案,對我來說甚是頭大。不得不說這是對傳統前端的一次大過濾,之前仗著html,css,js混飯吃的前端兒們,壓力越來越大,我就是這樣的一個例子。壓力越大,只要不放棄,成長的也越快啊,所以,咬牙就咔咔開始幹。 需求:一個H5分享頁面
H5與App的互動(WebViewJavascriptBridge)
最近有時間整理下H5與APP的互動框架(WebViewJavascriptBridge),既可以和ios互動也可以和安卓互動,我只做了和IOS的互動,所以只闡述和IOS的互動。 1:JS端的操作 /* WebViewJavascriptBridge框架使用 這段程式碼是固
H5與android原生的JS互動
公司最近接手了一個電信的專案,其中最關鍵的技術就是H5頁面與android的互動。因為之前專案中H5與原生介面的載入動畫是分開寫的,導致大小以及效果有差距,所以我才有接觸兩者之間互動的學習機會。簡單
H5頁面與APP的互動
概述 APP呼叫H5頁面時,出現有些頁面頁頭重複的現象,需去掉H5頁頭使用原生APP頁頭。 解決方案 方案一: 前端在網頁中寫一個隱藏頭部的方法,客戶端直接呼叫; 方案二: 使用userAgent判斷當前頁面是否在webView裡開啟: 兩種判斷方式: 1.與
與app的互動
export const connectWebViewJavascriptBridge = (callback) => { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge) }
通過頁面呼叫APP【H5與APP互通】
http://www.cnblogs.com/carlos-guo/p/3945112.html 現在H5和App原生的內容原來越互通,所涉及的業務也越來越複雜和融合,所以如何互相之間方便的呼叫才是王道。 場景1 比如用hybrid獲取地理位置和簡訊資訊,這當然
JS與Android原生互動
JS與Android原生互動 在專案的開發中我們會遇到android 原生與Html5的混合開發,我們可能會需要在android中呼叫js裡面的方法進行資料互動或其他的特殊處理,又或者在Html頁面呼
h5和iOS原生互動,h5和iOS互相傳值
前言 : h5和iOS原生互動,互相傳值,下面程式碼是完整的.M檔案 簡單實現h5和原生互動,互相傳值。 // // ViewController.m // 原生-H5簡單互動 // // Created by Mr Yang on 2018/7/23. // C
BLE 藍芽 與APP 得互動 內設 外設
藍芽設定 CoreBluetooth框架的核心其實是:peripheral和central,對應他們分別有一組相關的API和類 這兩組api粉筆對應不同的業務常見:左側叫中心模式,就是以你的app作為中心,連線其他的外設的場景;而右側稱為外設模式,使用`手機作為外設`
h5 與原生 app 互動的原理
現在移動端 web 應用,很多時候都需要與原生 app 進行互動、溝通(執行在 webview中),比如微信的 jssdk,通過 window.wx 物件呼叫一些原生 app 的功能。所以,這次就來捋一捋 h5 與原生 app 互動的原理。 h5 與原生 app 的互動,本質上說,就是兩種呼叫:
Hybrid開發-----H5與原生App互動
http://www.cnblogs.com/yexiaochai/p/5813248.htmlhttp://www.cnblogs.com/nildog/p/5536081.htmlHybrid開發效率高、跨平臺、低層本 Hybrid從業務開發上講,沒有版本問題,有BUG能
環法競猜項目:H5與原生APP交互方式
一個 lua shp stringify response else all alert 延遲 APP調用H5函數 (1)登錄功能——調起APP的登錄頁面 操作:點擊h5頁面的"去登錄"按鈕,執行appLogin函數,檢測window對象是否有WebViewJavascri
H5與原生Android互動
前言: 在專案中有時候需要APP和H5之間相互呼叫方法來實現某些功能,本文主要介紹Android是怎麼實現相互呼叫對方的方法。 H5呼叫APP的方法——APP來實現一些功能 H5將所需要的引數通過JSon字串的形式傳給APP Android——根據webview
shiro與app利用token進行互動的解決方案
shiro在收到請求時會預設讀取cookie裡的資料來判別客戶端的身份,然而我的專案沒有用cookie,伺服器也不處理cookie資訊,我們看看shiro讀取cookie的程式碼: //SimpleCookie類的readValue方法 public Stri
h5頁面與Android原生頁面互動
Android頁面內巢狀h5頁面已經是隨處可見了。在Android原生頁面和h5頁面的取捨上那些不是本文的重點。重點是,如此多的頁面用網頁來寫,那麼必定涉及到網頁與原生的互動,俗稱js互動。 目標:h5頁面點選按鈕Android端接收到網頁傳給的json資料。
微信中通過頁面(H5)直接打開本地app的解決方案
ids 支持 完全 系統默認 domain rdquo bili 通過 解決 簡述 微信中通過頁面直接打開app分為安卓版和IOS版,兩個的實現方式是完全不同的。 安卓版實現:使用騰訊的應用寶,只要配置了“微下載”之後,打開鏈接騰訊會幫你判斷本地
Flutter的需要與原生互動的一些常用庫
轉自: https://github.com/AweiLoveAndroid/Flutter-learning/blob/master/readme/Flutter%E7%9A%84%E9%9C%80%E8%A6%81%E4%B8%8E%E5%8E%9F%E7%94%9F%E4%BA%A4%E4
h5與mui開發app標題的滑動實現和樣式追蹤
mui.init({ gestureConfig: { longtap: true //預設為false }, swipe:true, //啟用右滑關閉功能 pullRefresh : { container:".mui-scroll-wrappe
小程式 與 App 與 H5 之間的區別
小程式的實現原理 根據微信官方的說明,微信小程式的執行環境有 3 個平臺,iOS 的 WebKit(蘋果開源的瀏覽器核心),Android 的 X5 (QQ 瀏覽器核心),開發時用的 nw.js(C++ 實現的 web 轉桌面應用)。 平臺渲染js 執行環境 iOSWKWe