vue用戶長(zhǎng)時(shí)間不操作退出到登錄頁(yè)的兩種實(shí)現(xiàn)方式
問(wèn)題描述
產(chǎn)品說(shuō),出于安全考慮,用戶長(zhǎng)時(shí)間不操作,就回到登錄頁(yè)面,讓用戶重新登錄,就像銀行的app一樣。本文就記錄一下實(shí)現(xiàn)這種效果的兩種方式,分別是前端控制和后端控制,各有細(xì)節(jié)及適用使用場(chǎng)景
前端控制(方式一)
思路
首先,用戶長(zhǎng)時(shí)間不操作具體表現(xiàn)形式是啥?其實(shí)就是事件是否長(zhǎng)時(shí)間沒(méi)有被觸發(fā)執(zhí)行。
比如用戶長(zhǎng)時(shí)間不操作,就沒(méi)有鼠標(biāo)點(diǎn)擊(click)事件、鼠標(biāo)滾輪(mousewheel)事件、鼠標(biāo)移動(dòng)(mousemove)事件之類(lèi)的,我們只需要監(jiān)聽(tīng)這些事件,如果這些事件長(zhǎng)時(shí)間沒(méi)有觸發(fā),就說(shuō)明用戶長(zhǎng)時(shí)間未操作,然后路由跳轉(zhuǎn)到登錄頁(yè)面即可。
這三個(gè)事件我選擇的是比較實(shí)用的鼠標(biāo)點(diǎn)擊事件,我們知道,一般來(lái)說(shuō)項(xiàng)目的第一個(gè)頁(yè)面是登錄頁(yè)面,所以在登錄頁(yè)面用戶點(diǎn)擊登錄按鈕的時(shí)候,就記錄一下點(diǎn)擊登錄按鈕的時(shí)間,存儲(chǔ)到sessionstorage中去,當(dāng)跳轉(zhuǎn)到主頁(yè)面的時(shí)候,當(dāng)用戶每點(diǎn)擊一次頁(yè)面,就更新一下sessionstorage中的存儲(chǔ)的時(shí)間,同時(shí)也給頁(yè)面綁定一個(gè)循環(huán)定時(shí)器,間隔一段時(shí)間就把當(dāng)前時(shí)間和sessionstorage儲(chǔ)存的上一次點(diǎn)擊事件的時(shí)間做一個(gè)差值對(duì)比,當(dāng)差值超過(guò)一定時(shí)間,就強(qiáng)制用戶退出到登錄頁(yè)面即可。
代碼
login.vue頁(yè)面
// html <el-button type="primary" @click="loginIn">點(diǎn)擊登錄</el-button> // js methods: { loginIn() { // 存第一份點(diǎn)擊的時(shí)間 sessionStorage.setItem("lastClickTime", new Date().getTime()); // 模擬后端返回存一個(gè)token sessionStorage.setItem('token',"token") this.$router.push({ path: "/", }); }, }
Home.vue頁(yè)面
<template> <div class="homeBox"> <!-- 左邊是菜單層級(jí) --> <div class="left"> <div class="leftNav"> <el-menu :default-active="activeIndex" class="elMenu" background-color="#333" text-color="#B0B0B2" active-text-color="#fff" :unique-opened="true" router ref="elMenu" > <el-menu-item index="/vue"> <i class="el-icon-location-outline"></i> <span slot="title">vue頁(yè)面</span> </el-menu-item> <el-menu-item index="/react"> <i class="el-icon-star-off"></i> <span slot="title">react頁(yè)面</span> </el-menu-item> <el-menu-item index="/angular"> <i class="el-icon-pear"></i> <span slot="title">angular頁(yè)面</span> </el-menu-item> </el-menu> </div> </div> <!-- 右邊是視圖層級(jí) --> <div class="right"> <div class="rightTop"> <el-button type="primary" plain @click="loginOut">登出</el-button> </div> <div class="rightBottom"> <router-view></router-view> </div> </div> </div> </template> <script> export default { name: "Home", data() { return { activeIndex: this.$route.path, timer: null, }; }, created() { /* 第一步: 組件初始化加載就綁定監(jiān)聽(tīng)點(diǎn)擊事件,注意:addEventListener的第三個(gè)參數(shù),這里要加上。 因?yàn)榈谌齻€(gè)參數(shù)決定了是冒泡還是捕獲(false冒泡默認(rèn),true捕獲),因?yàn)榻壎ūO(jiān)聽(tīng)點(diǎn)擊事件,我們是在最 頂層的DOM位置進(jìn)行捕獲點(diǎn)擊事件,所以第三個(gè)參數(shù)true,要加上的,這樣的話,內(nèi)層的任意地方的點(diǎn)擊事件 我們就都能監(jiān)聽(tīng)到了,然后存儲(chǔ)一下點(diǎn)擊的時(shí)間 */ window.addEventListener( "click", () => { // 為了方便,我們把點(diǎn)擊事件的時(shí)間直接存到sessionStorage中去,這樣方便獲取比較 sessionStorage.setItem("lastClickTime", new Date().getTime()); }, true ); }, mounted() { /* 第二步: 組件初始化加載時(shí)也要綁定一個(gè)定時(shí)器,通過(guò)定時(shí)器定時(shí)輪詢,去對(duì)比當(dāng)前時(shí)間和上次點(diǎn)擊的時(shí)間的差值 */ this.isTimeOut(); }, methods: { isTimeOut() { // 使用定時(shí)器之前,要清除一下定時(shí)器 clearInterval(this.timer); this.timer = setInterval(() => { let lastClickTime = sessionStorage.getItem("lastClickTime") * 1; // 把上次點(diǎn)擊時(shí)候的字符串時(shí)間轉(zhuǎn)換成數(shù)字時(shí)間 let nowTime = new Date().getTime(); // 獲取當(dāng)前時(shí)間 console.log("當(dāng)前時(shí)間和之前點(diǎn)擊時(shí)間", nowTime, lastClickTime); // 假設(shè)我們需求是:5秒鐘不進(jìn)行點(diǎn)擊操作,就提示登錄退出 if (nowTime - lastClickTime > 1000 * 5) { // 提示一下用戶 this.$message({ type: "warning", message: "超時(shí)了,已退出登錄" }); // 這里要清除定時(shí)器,結(jié)束任務(wù) clearInterval(this.timer); // 最后返回到登錄頁(yè) this.$router.push({ path: "/login" }); } }, 1000); }, }, beforeDestroy() { // 最后一步,離開(kāi)頁(yè)面的時(shí)候,清除一下定時(shí)器,也解綁點(diǎn)擊事件 clearInterval(this.timer); window.removeEventListener("click", () => {}, true); }, }; </script>
這里注意一下,層級(jí)對(duì)應(yīng)關(guān)系,我項(xiàng)目搭建的層級(jí)關(guān)系是Home.vue頁(yè)面是App.vue頁(yè)面的里面一層,也有對(duì)應(yīng)的視圖,視圖對(duì)應(yīng)的也是整個(gè)頁(yè)面的關(guān)系。根據(jù)層級(jí)和路由表路由視圖router-view關(guān)系,選擇合適的層級(jí)去綁定對(duì)應(yīng)的點(diǎn)擊事件和定時(shí)器即可。
即層級(jí)關(guān)系是要選擇和login.vue層級(jí)平行的下一級(jí)才行,否則就會(huì)在login.vue頁(yè)面也會(huì)執(zhí)行定時(shí)器和點(diǎn)擊綁定事件了
效果圖
后端控制(方式二)
思路
這種后端控制方式限制性沒(méi)有前端控制強(qiáng),但是也是可以用的。
我們知道用戶長(zhǎng)時(shí)間不操作就不會(huì)有發(fā)請(qǐng)求,這種方式我們和后端商定如下:
當(dāng)用戶這一次的請(qǐng)求和上一次請(qǐng)求的間隔時(shí)間超過(guò)一定時(shí)間,比如超過(guò)半小時(shí)。那么后端返回的狀態(tài)碼就不是200了,就是一個(gè)特殊的狀態(tài)碼,比如是4567這個(gè)狀態(tài)碼,那么我們?cè)谇岸说捻憫?yīng)攔截器中就可以加一個(gè)判斷,如果狀態(tài)碼是4567就說(shuō)明請(qǐng)求超時(shí)了,說(shuō)明用戶長(zhǎng)時(shí)間未操作,這個(gè)時(shí)候直接路由跳轉(zhuǎn)到登錄頁(yè)面即可
后端通過(guò)JWT機(jī)制去控制返回的狀態(tài)碼
代碼
這里main.js中的Vue的實(shí)例對(duì)象我們將其掛載到全局對(duì)象window上,方便我們?cè)陧憫?yīng)攔截器中使用vm對(duì)象上的路由跳轉(zhuǎn)方法
main.js文件
// 掛載到window對(duì)象上 window.vm = new Vue({ store, router, render: h => h(App), }).$mount('#app')
響應(yīng)攔截器文件
http.interceptors.response.use((res) => { console.log('注冊(cè)到全局上',vm); var code = res.data.code; if(code == 4567){ // 4567是超時(shí)狀態(tài)碼,看到這個(gè)標(biāo)識(shí)我們就讓用戶退出登錄 // 注意,這個(gè)時(shí)候路由跳轉(zhuǎn)就不是this.$router.push()了 vm._router.push({ path: "/login" }); } return res.data }, (error) => { // console.log(error) return Promise.reject(error); })
打印vm實(shí)例對(duì)象
所以在響應(yīng)攔截器中路由跳轉(zhuǎn)變成了vm._router.push({ path: "/login" })了
總結(jié)
上述兩種方式的思路都可以使用,具體使用哪種方式,視情況而定
到此這篇關(guān)于vue用戶長(zhǎng)時(shí)間不操作退出到登錄頁(yè)的兩種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)vue用戶長(zhǎng)時(shí)間不操作退出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決vant的Cascader級(jí)聯(lián)選擇組建css樣式錯(cuò)亂問(wèn)題
這篇文章主要介紹了解決vant的Cascader級(jí)聯(lián)選擇組建css樣式錯(cuò)亂問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07element-UI el-table修改input值視圖不更新問(wèn)題
這篇文章主要介紹了element-UI el-table修改input值視圖不更新問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02webpack+vue.js實(shí)現(xiàn)組件化詳解
vue的開(kāi)發(fā)體驗(yàn)還是比較愉悅的。首先文檔非常友好,所以上手會(huì)比較快。其次,配合webpack和vue-loader,每個(gè)頁(yè)面都是一個(gè).vue文件,寫(xiě)起來(lái)很方便。所以很適合做組件化開(kāi)發(fā),這篇文章我們就來(lái)一起看看webpack+vue.js如何實(shí)現(xiàn)組件化。2016-10-10vue實(shí)現(xiàn)富文本編輯器詳細(xì)過(guò)程
Vue富文本的實(shí)現(xiàn)可以使用一些現(xiàn)成的第三方庫(kù),如Quill、Vue-quill-editor、wangEditor等,這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)富文本編輯器的相關(guān)資料,需要的朋友可以參考下2024-01-01vue 項(xiàng)目 iOS WKWebView 加載
這篇文章主要介紹了vue 項(xiàng)目 iOS WKWebView 加載問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04使用vue-cli3 創(chuàng)建vue項(xiàng)目并配置VS Code 自動(dòng)代碼格式化 vue語(yǔ)法高亮問(wèn)題
這篇文章主要介紹了使用vue-cli3 創(chuàng)建vue項(xiàng)目,并配置VS Code 自動(dòng)代碼格式化 vue語(yǔ)法高亮問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05