後插件時代頁面如何喚起本地程序

很多時候為了方便,我們都需要從頁面上啟動一些本地的程序,從客戶端來實現更好的操作,比如 QQ 快速登錄,點擊旺旺圖標開啟客戶端等,這種在以往可以通過插件實現通信,例如 IE 的 ActiveX,早期 Chrome 與 Firefox 支持的 NPAPI,但 NPAPI 提供的許可權過大,導致了很多安全和性能問題,目前現代瀏覽器已停止支持,實際上單純頁面實現與本地程序進行通訊,我們有更通用的方式實現。

這裡暫時僅討論 Windows 的情況,Mac 和 Linux 還需要其他方式實現。

註冊協議(Register protocol)

註冊協議是一種用於通過鏈接發送,接收和處理信息的方法,瀏覽器可以處理的常見協議包括http,https,ftp 和 mailto。為了實現查看通過特定協議發送的信息,這種協議必須註冊在註冊表中註冊,常見的我們可以通過點擊一個郵件地址調起第三方郵件客戶端。

協議被註冊後,該網址就可以由指定的程序(瀏覽器或第三方查看器)進行處理。例如 mailto://abc<AT>xyz.com 可以使用註冊了協議 mailto 的郵件客戶端新建一封收件人地址為 abc<AT>xyz.com 的郵件。同理我們可以利用這種方式實現在瀏覽器中頁面調起本地程序。

除默認協議外,其他協議需要通過創建一個 .reg 文件來進行註冊,例如註冊一個 test:// 協議:

[HKEY_CLASSES_ROOT est]@=「URL:test Protocol""URL Protocol"=""[HKEY_CLASSES_ROOT estshell][HKEY_CLASSES_ROOT estshellopen][HKEY_CLASSES_ROOT estshellopencommand]@=""C:\Program Files\Application\program.exe" "%1」"

運行這個 .reg 文件註冊後,瀏覽器就可以調用 program.exe 處理 test://。當瀏覽器碰到 test://… 鏈接時,自動調用 program.exe,並把 test://… 地址作為第一個參數傳遞給 program.exe,通過 program.exe 判斷傳入的參數格式,若正確則檢查系統中是否存在 program.exe 進程,不存在會提示「系統檢測到您的機器上沒有啟動 program」,若存在則判斷 program 是否已登錄,沒有登陸的話調起後先進行登錄,若已登陸則直接進行後續操作。

也就是說 test://… 後續的信息是交給 program.exe 進行處理的,在這裡我們就可以針對不同情況在鏈接中加入一些內容,也可以通過請求一個 URL,伺服器根據 URL 傳遞的 uid 和其他的一些參數,返回一段新的 HTML,新的 htm 中包含了自動運行的 js,執行完後程序得到響應,也可以將相關 js 包含在本頁,點擊後直接交給 js 函數進行處理。

淘寶頁面中的 URL 啟動

旺旺有一個專門的服務叫做「旺旺亮燈」,實現原理是在 html 頁面中,寫一些特定 id 的元素,最外層的 span 將在相關 js 載入的時候動態的進行渲染,顯示成旺旺是否在線的圖標以及附加上相關的單擊事件,這樣在單擊圖標的時候,便會由 js 來進行處理。從代碼中看還支持 NPAPI 插件。當然如果發現本機沒有安裝旺旺的情況下,會跳轉到 web 版旺旺的頁面。

QQ 郵箱快速登錄

如果我們在本機電腦上啟動了 QQ,再使用瀏覽器訪問 QQ 郵箱登錄頁,頁面會提示我們已經登錄了的 QQ,點擊即可登錄。

QQ 的實現方式是在客戶端開一個 Server,瀏覽器裡面請求這個地址,當訪問 QQ 郵箱登錄頁時網頁會去訪問這個 Web Server,地址就是:127.0.0.1(localhost),由於這個 Web Server 是 QQ 建立的,所以 QQ 可以根據自己的登錄狀況給訪問者返回對應的信息。

我們來驗證一下,打開開發者工具,切換到網路請求,刷新頁面,過濾一下 localhost 的請求:

- 看一下完整響應:

var var_sso_uin_list=[{"account":」QQ賬號","client_type":65793,"face_index":528,"gender":1,"nickname":"火狐測試","uin":」QQ賬號","uin_flag":512}];ptui_getuins_CB(var_sso_uin_list);

很明顯是當前登錄的用戶信息。

- ping 一下這個請求的 domain:

正在 Ping localhost.ptlogin2.qq.com [127.0.0.1] 具有 32 位元組的數據

顯示是 127.0.0.1。

- 現在我們驗證下是否是 QQ 開了這個 Server,查看哪個程序佔用了 4301 埠:

netstat -ano | findstr "4301」TCP 127.0.0.1:4301 0.0.0.0:0 LISTENING 9872

- 得到 pid 我們就可以看否是 QQ 在監聽這個埠了:

tasklist | findstr 「9872"QQ.exe 9872 Console 1 170,380 K

然後通過隨機數與郵箱伺服器配合加上 HTTPS 防止數據竊聽。

目前個人覺得 QQ 的方式較好,旺旺由於多個大型站點(淘寶、天貓、阿里巴巴中文站、國際站)分支較多,似乎沒有一個統一的方式來管理,會造成部分情況下無法調起的情況。

參考鏈接:Registering an Application to a URI Scheme


推薦閱讀:

Firefox 49.0 正式版用戶特性介紹
Google Chrome成功之路

TAG:前端开发 | 网页浏览器 | 火狐浏览器Firefox |