Android 原生webview傳遞header前端H5如何接收

開發背景
跟其餘公司合做的一個項目,傳遞參數的方式爲原生經過自定義header頭參數,由前端來接收。
踩坑
1 原生傳參
安卓原生傳參的方式很簡單,經過webview.loadUrl這個方法,以下:



javascript

 

Map<String, String> map = new HashMap<String, String>();
   map.put("Payment-Token", "*****");
   myWebView.loadUrl(myEdit.getText().toString(), map);

2 H5接收參數
也很簡單,在網上查到的是ajax的方式,可是最後項目用的原生獲取header參數的,不必爲了接收個參數,在我大VUE框架裏引入jquery,以下:
php

 

let req = new XMLHttpRequest();
      req.open('GET', document.location, false);
      req.send(null);
      let paymentToken = req.getResponseHeader('payment-token') ? req.getResponseHeader('payment-token') : '';
      this.paymentToken = paymentToken;
      if (paymentToken == '') {
        this.setShade('訂單信息獲取失敗');
      }

你看,多麼簡單。而後測試的時候就被啪啪打臉了。前端說沒收到參數,原生說傳了,互相僵持了一下午,最後用修改UserAgent的方式來傳遞參數的前端

myWebView.getSettings().setUserAgentString("****");

今天開會,以爲這種方式不行不正規,仍是要用以前loadUrl的方式傳遞header參數,突然公司的大佬一句話點醒了我,純前端VUE只能接收到response的header。java

重點來了
請求一個網頁其中包括了一次request(請求)以及一次response(響應)。因此,咱們常說的header頭也有兩個,一個是request的header頭,一個是response的header頭。問題點就在這,圈起來。原生那邊發的是request的header,而H5則接收的是response的header。
這個時候服務器的做用就來了,公司用的是nginx服務器,我在其中作了一些配置,邏輯就是獲取request中的header參數,而後動態設置到response的header中,打完收工,代碼以下

python

add_header 'Payment-Token' '$http_payment_token';

其中也能夠看出,單純前端VUE項目與渲染頁面式前端項目(php,python)項目的區別,前者的權限沒有後者的權限那麼多,像php能直接經過Request->header的方式讀取request的參數,而VUE則不行。jquery


咱們來看看如下幾個webview使用的案列。android

參考文獻:ios

WebView詳解與簡單實現Android與H5互調nginx

案例一headerweb

直接上需求效果圖:

需求:WebView添加header,h5讀取頭部,而且隱藏底部菜單欄。

須要添加的header數據:ECR-APP:android

咱們平時大多數狀況使用的是loadUrl(String url)加載方法,下面咱們來看另外一個loadUrl構造方法。

loadUrl(String url, Map<String, String> additionalHttpHeaders)

參數additionalHttpHeaders字面上的意思是:額外的http頭部信息。這個方法是Android 2.2 (也就是API 8),WebView新增長了一個接口方法,就是爲了便於咱們加載網頁同時又能夠發送HTTP頭信息的。

看看具體的使用:

    HashMap<String, String> header = new HashMap<>();
    header.put("ECR-APP", "android");

    mWebView.loadUrl("http://m.test.366ec.net/Default2c.aspx",header);

立刻運行效驗一下:

網頁上底部的菜單已經去掉了。

案例二cookie

cookie用於記錄用戶登陸信息,用戶下次進入須要登陸的界面再也不須要重複登陸。

先看看需求:

會一直出現登陸界面。那麼怎麼解決屢次登陸問題?WebView會將加載的url經過http請求傳輸到服務器。那麼Cookie信息會經過header傳遞過去。

設置cookie代碼以下:

private void syncCookieToWebView(String url, List<String> cookies) {
        CookieSyncManager.createInstance(this);
        CookieManager cm = CookieManager.getInstance();
        cm.setAcceptCookie(true);
        if (cookies != null) {
            for (String cookie : cookies) {
                cm.setCookie(url, cookie);//注意端口號和域名,這種方式能夠同步全部cookie,包括sessionid
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
            CookieManager.getInstance().flush();
        } else {
            CookieSyncManager.getInstance().sync();
        }
    }


如下是調用代碼:

 

  List<String> cookies = new ArrayList<>();
    //鍵值對類型  用等號("=")鏈接    具體根據後臺給定
    cookies.add("StoreManagerTicket=" + "加密token");//根據後臺協商而定
    syncCookieToWebView("加載的地址", cookies);

CookieManager會將這個Cookie存入該應用程序/data/data/databases/目錄下的webviewCookiesChromium.db數據庫的cookies表中。打開網頁,WebView從數據庫中讀取該cookie值,放到http請求的頭部,傳遞到服務器。

運行一下,看看還會出現屢次登陸的問題嗎?

跳轉正常,沒有出現屢次登陸的問題。

案例三注入js

不知道你在項目中遇到這樣的場景沒有?手機端與h5交互,提供數據支持。如調本地相機,獲取到的圖片上傳到網頁;調用定位返回地址給網頁;調用二維碼掃描界面返回掃描結果等等。

以下,有這樣一個場景,網頁上有【掃描】圖標,點擊打開手機掃描界面,掃描成功後上傳掃描結果。那麼在手機端通常會有以下方法:

JsOpenScanFunction(String callbackFunction)

參數callbackFunction表示掃描成功後webview.load調用的方法而且只有一個參數(掃描結果)。

通常前端h5會這樣進行調用Android手機端打開二維碼的方法:

//callback回調方法
window.JsInterface.JsOpenScanFunction(callback)

ios端會這樣調用:

window.webkit.messageHandlers.JsOpenScanFunction.postMessage(callback)

在h5端會分步處理,無疑會增長開發人員的工做量,試想一下,若是交互的地方不少,那麼h5端開發人員做何感想?並且後期的維護也是一件很是繁瑣的事情,就沒有更好的方案嗎?

若是h5端能夠像調用本地方法那樣簡單調用手機端方法,那不是很是fashion。

那麼就須要分別在Android端和ios端分佈注入js代碼,方便h5端調用。

注入的方式以下:

@Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        if (mIsAddJsCode) {//默認true
            mIsAddJsCode = false;
            mWebView.loadUrl("javascript:" + "function JsOpenScanFunction(s) {\n    window.JsInterface.JsOpenScanFunction(s);\n}");
        }
    }


在onPageStarted方法下注入js方法:

function JsOpenScanFunction(s) {
    window.JsInterface.JsOpenScanFunction(s);
}


這樣h5只須要調用JsOpenScanFunction(s)方法就能夠實現不一樣平臺調用二維碼掃描的功能。今後媽媽在已不擔憂多端調用的問題了。

注意:JsOpenScanFunction(s) 方法,須要前端和移動端事先約定。
參考:https://blog.csdn.net/u012551350/article/details/56674602

相關文章
相關標籤/搜索