用戶離開頁面時(shí)向服務(wù)器發(fā)送數(shù)據(jù)
背景
希望在用戶離開頁面時(shí),向服務(wù)器發(fā)送數(shù)據(jù)記錄用戶信息
對于這個(gè)需求,相信大多數(shù)前端都不會陌生,畢竟大多數(shù)產(chǎn)品都需要收集用戶退出頁面的數(shù)據(jù),那拆分這個(gè)需求,可以把它分成兩步驟:
監(jiān)聽用戶離開頁面
向服務(wù)器發(fā)送數(shù)據(jù)
技術(shù)分析
監(jiān)聽
所謂離開頁面,那我們可以大致認(rèn)為是一下情況:
頁面刷新
頁面跳轉(zhuǎn)
關(guān)閉tab或?yàn)g覽器
要監(jiān)聽這類情況,我們可以使用瀏覽器內(nèi)置的監(jiān)聽事件:
beforeunload,unload
注意:這里針對不同的兼容性以及要求,兩種事件的選用以及所需要的兼容處理各不相同,這里不細(xì)說
發(fā)送數(shù)據(jù)
發(fā)送數(shù)據(jù),也就是發(fā)送一次post請求,這里可以使用的方法也很多,包括http、axios、fetch、etc
總結(jié)
問題解決!大吉大利!
下一步思考
數(shù)據(jù)發(fā)送是一個(gè)異步請求,理所當(dāng)然會發(fā)生請求未完成發(fā)送但頁面已經(jīng)丟失的情況,為了能夠使數(shù)據(jù)更有效,再思考改進(jìn)點(diǎn)
方法很多,這里我們選用在Service worker 中發(fā)送請求
Service Worker
沒聽說過的可以百度了解下,并不是一個(gè)新技術(shù)了
簡單說:它主要運(yùn)行于瀏覽器后臺,也就是說不需要頁面打開我們就能執(zhí)行程序
理由分析
此處選擇它的理由很簡單,既然請求是異步,那我們就把這個(gè)超~長~的執(zhí)行過程放在后臺,前臺程序只需要通知下:
前臺程序:SW(Service Worker),你去幫我跑個(gè)腿,發(fā)個(gè)郵件
SW:好的?。ǜ苫钊チ耍?/p>
前臺程序:那我下班了
這樣的話,服務(wù)于用戶的前臺程序需要做的事情就簡單了!
代碼實(shí)現(xiàn)
注冊Service Worker
創(chuàng)建service-worker.js放置于public文件夾下(vue項(xiàng)目)
在需要使用服務(wù)的頁面執(zhí)行代碼
這樣咱們就注冊好了!
防報(bào)錯(cuò)
由于SW并非一個(gè)全平臺都有的功能,所以為了防止報(bào)錯(cuò),我們需要進(jìn)行一下判斷
這里我又添加了一個(gè)卸載事件,由于service worker被裝載后會被緩存,為了方便調(diào)試,我們默認(rèn)先進(jìn)行一次卸載以保證我們運(yùn)行的文件是最新的
發(fā)送數(shù)據(jù)
Service worker提供也僅支持一些事件,這里我們選用message事件
前臺程序調(diào)用 postMessage時(shí),可以在sw中觸發(fā)message事件
sw運(yùn)行在后臺,它就跟隔壁公司的程序員一樣,對你的工作完全不了解,因此我們需要告訴它去做什么,以及這件事需要的信息:
前臺程序:SW幫我干個(gè)事!去送個(gè)信!地址是xxxxxxx,信件內(nèi)容是xxxxxx
SW:收到!
前臺程序:下班!
數(shù)據(jù)接收
現(xiàn)在轉(zhuǎn)到SW接收部分,直接上代碼
這里我們定義了打工人service-worker,并給它創(chuàng)建一個(gè)可以干的事情的目錄(methods),根據(jù)收到的信息,去做對應(yīng)的事情
發(fā)送數(shù)據(jù)
接下來定義“送信”這件事
現(xiàn)在咱們的SW會送信了!
工具封裝
現(xiàn)在,在我們前臺有了一套工作流:
index.vue: 監(jiān)聽用戶離開頁面 -> 注冊sw -> 發(fā)送數(shù)據(jù)給sw
現(xiàn)在我們把它封裝!
根據(jù)要求,這里我們預(yù)判到既然我們做了頁面離開,產(chǎn)品一定也會想要收集頁面進(jìn)入啊!很合理吧!機(jī)智的我們于是簡單暴露了發(fā)送方法,用來隨時(shí)可以調(diào)用!
使用
這樣,需求就搞定了!萬事大吉!