上個月探討了 一次頁面與應用之間的通訊,主要利用瀏覽器擴展來進行通信。此次來詳細研究下具體實現。javascript
上個月其實還思考了一種結合性拉起應用的方式。因爲經過URI拉起應用,js端沒法接受到任何反饋,意味着沒法判斷應用是否有被拉起。因而思考了另外一種方式:css
這是一種一套代碼多端可行性的方案,可是因爲期間通訊過程較爲繁瑣(惟一Id值,當前系統環境等等),可能出現不可預知的bug,暫時放棄了。之後有時間再詳細研究一番。html
ie 之因此放到第一位,是由於它太特殊了。沒有擴展,ie10往下不支持websocket。拉起應用除了不可靠的URI就只剩下只此一家的 new ActiveXObject(str),其中str表明註冊列表中拉起應用的腳本和配置。粗看和擴展拉起應用很類似,可是卻要複雜不少。IE方面等研究出成果了再添加。前端
如今主流瀏覽器基本都支持擴展了。因此咱們主要仍是以經過擴展拉起應用爲主。先把準備代碼寫好(判斷系統,瀏覽器)。而後再判斷是否安裝了擴展。js是不能去改變,訪問瀏覽器是否安裝了擴展的,只能由擴展來告訴頁面。咱們在擴展的配置文件裏頭配置好content.js文件在頁面渲染完成後加載,而後 content.js 裏頭添加以下代碼:java
var miniDom = document.createElement('div');
miniDom.setAttribute('id', 'test')
document.body.appendChild(miniDom); // 判斷插件安裝
複製代碼
只要找到id爲設定好的特殊值就說明安裝了擴展web
擴展是能夠和頁面通訊的(相互監聽對方的事件,並獲取值),可是不推薦。一來各個瀏覽器之間寫的通訊代碼不相同,增大了項目體積和難度,二來出了問題很差排查,層級太深。通訊過程是一個 頁面-->content-->background-->native的過程,中間任何一個環節有問題都須要花大量時間排查。而擴展的主要做用就是拉起應用並告訴頁面便可,只須要觸發事件,不須要傳遞數據。chrome
IE固然只能經過輪詢刷接口來通訊了。由於在系統中,拉起一個應用就是起了一個服務器,它有本身的端口號。如今就是須要肯定應用的端口號。固然能夠經過擴展來傳遞,這很簡單直接。也能夠經過ws詢問一個區間的端口號來獲取。ws 鏈接某一個端口,若是走了onerror回調就繼續下一個端口,若是onopen了就發送一個密令過去,onmessage回來與約定一致即正確端口。這個方法繁瑣點,可是bug會少一些。建議使用遞歸。swift
將IE,chrome,firefox,edge,safari拉起應用的代碼處理整合到一塊兒,只須要單獨將IE拎出來考慮就好了。可是真正困難的仍是edge和safari的擴展部分。須要C#和swift兩門新語言才能徹底弄懂。這也就不會出如今前端er的考慮範圍了。瀏覽器
IE。new 一個activeObject對象,經過和這個對象的對話來確認拉起應用,並經過輪詢http請求來通訊。服務器
非IE。首先確認是否安裝擴展,擴展拉起應用,經過websocket 進行實時通訊。
此案例參考 IBM的aspera的通訊方式。
做者簡介: 張栓,人和將來大數據前端工程師,專一於 html/css/js 的學習與開發。