Android Webview攔截ajax請求

wendux發表於2017-11-07

Android Webview雖然提供了頁面載入及資源請求的鉤子,但是對於h5的ajax請求並沒有提供干涉的介面,這意味著我們不能在webview中干涉javascript發起的http請求,而有時候我們確實需要能夠截獲ajax請求並實現一些功能如:統一的網路請求管理、cookie同步、證照校驗、訪問控制等。

那麼究竟有沒有辦法能在Webview中攔截ajax請求呢?

我百度谷歌一圈後,找到了這篇文章,你可以參考一下:http://blog.csdn.net/kpioneer123/article/details/51438204 。如果沒有看懂,那就不用理會了,畢竟本文絕不會撩起你的興趣,然後卻戛然而至的,好了,我們還是直奔主題吧。

思路

雖然在 Webview中無法直接攔截 ajax請求(其實在shouldInterceptRequest 中是可以收到ajax請求的,但是遺憾的是取不到請求引數,這樣也是沒有意義的), 我們可以轉換思路,能不能在js中將所有的請求轉發到native中,這樣也就達到了相同的目的。如果可以,那就需要一種在javascript和native之間通訊的橋樑(javascript bridge),通過它,javascript將請求資訊傳遞給native, native完成真正的請求後再將結果資料傳遞給javascript。那麼我們的思路就是:

  1. 在javascript中攔截所有ajax請求,然後通過javascript bridge將請求資訊傳遞給native
  2. native收到請求資訊後,進行一些與處理邏輯,然後完成本次請求,將請求結果通過javascript bridge再回傳給javascript.

這樣,在第二步native上收到請求資訊後,我們就可以進行統一的網路請求管理、cookie同步、證照校驗、訪問控制。思路雖然簡單,但實現起來卻是比較麻煩,因為需要前端和native都需要做不少的工作。那麼有什麼簡單的方法嗎?當然有!

輪子

fly.js 是一個支援請求重定向的輕量級、跨平臺的Javascript http請求庫 ,前端可以使用它輕鬆發起網路請求,它會自動將請求轉發至native. 現在解決了第一個問題,接下來我們需要選一個javascript bridge, 而現在開源的javascript bridge挺多,你可以選擇任意一個你喜歡的。但是,在此強烈推薦一下 DSBridge它是一個使用非常簡單並支援同步的跨平臺javascript birdge, 最關鍵的的是DSBridge 的demo中就有接收處理fly.js轉發的http請求的示例,並且給出了okhttp的實現,並且, fly.js 官方也提供了 DSBridge 的adapter. 下面我們以DSBridge為例,演示一下整個過程:

例項

前端

//引入dsbridge adapter
var adapter = require("flyio/dist/npm/adapter/dsbridge")
var EngineWrapper = require("flyio/dist/npm/engine-wrapper")
var dsEngine = EngineWrapper(adapter)
var fly = new Fly(dsEngine);

//接下來,通過fly發起的ajax請求都會轉發到native上
fly.post('/user', {
    name: 'Doris',
    age: 24
    phone:"18513222525"
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
複製程式碼

Native端

 @JavascriptInterface
 public void onAjaxRequest(JSONObject jsonObject, final CompletionHandler handler){
    //jsonObject 為fly adapter 傳給端的requerst物件
    //端上完成請求後,將響應物件通過hander返回給fly adapter
    //hanlder(response)
 }
複製程式碼

fly.js中dsbridge的adapter會呼叫Native的 onAjaxRequest方法,native只需實現這個方法即可,完整的請求實現可以參照 DSbridge demo中 AjaxHandler 的實現.

值得注意的是, fly.js並不是只支援DSBridge ,它可以支援任何javascript bridge,只是不同的javascript bridge的資料傳輸協議不同,需要分別提供一個adapter, 詳情請參考:fly.js之http engine及adapter .

最後

貼出fly.js和DSBridge的github地址,歡迎star ! 有什麼問題也可以關注我或留言。

fly.js: https://github.com/wendux/fly

DSBridge-Android: github.com/wendux/DSBr…

DSBridge-IOS: github.com/wendux/DSBr…

相關文章