以前都是開始一段廢話的,現在直接進入主題,首先介紹一下一些概念:
單頁應用:
優點:
- 具有桌面應用的即時性、網站的可移植性和可訪問性。
- 用戶體驗好、快,內容的改變不需要重新加載整個頁面,web應用更具響應性和更令人着迷。
- 基於上面一點,SPA相對對服務器壓力小。
- 良好的前后端分離。SPA和RESTful架構一起使用,后端不再負責模板渲染、輸出頁面工作,web前端和各種移動終端地位對等,后端API通用化。
- 對前端人員javascript技能要求更高,促使團隊技能提升。
- 不利於SEO。
- 初次加載耗時相對增多。
- 導航不可用,如果一定要導航需要自行實現前進、后退。
- 對開發人員技能水平、開發成本高。
多角色:項目設計中多角色參與,比如我現在做的系統,除了有個人用戶,還有開店的商戶進行登錄2種角色
session:這個不多說,后台系統判斷用戶活躍存在的一種身份憑證。PS:現在很多大型公司都自己做session管理
問題再現:
- 在一個瀏覽器中,首先使用個人用戶登錄(現在該瀏覽器針對該站點發送的請求為個人用戶的session)
- 然后在瀏覽器中新開一個標簽頁,同樣訪問該網址,然后安全退出,清除cookie保存的一些信息和服務器的session數據。然后使用商戶賬號進行登錄(現在整個瀏覽器針對於該域名,發送的請求都使用該商戶的session)
- 現在切換到第一個標簽頁,是個人的首頁,然后點一個功能按鈕,監控xhr的請求,你會發現個人用戶請求的session憑據並不是個人的,被商戶的標識覆蓋了,且占用了商戶的session去發送請求
-
這樣得到的結果肯定是錯的。所以必須解決該問題
測試淘寶:
- 登錄第一個賬戶
- 新開標簽頁輸入相同網址
- 網頁會自動跳轉到和標簽也一樣的頁面
- 退出登錄新的賬號,第一個標簽頁還是在第一個人的個人中心那里
- 登錄第二個賬戶,這個時候第一個標簽頁是第一個賬戶的個人信息,第二個標簽頁是第二個賬戶的個人信息
- 這個時候,瀏覽器針對這個域名,其實存儲的已經是第二個賬戶的所有信息了,包括session_id。所以點擊第一個標簽頁的任何操作,如果不刷新頁面的話(也就是單頁應用),會以第二個用戶的session_id去請求數據。但是淘寶是刷新整個頁面就不存在這個問題了。
- 這樣整頁刷新就是第二個賬戶的所有的信息了。如果系統多角色,而且多角色菜單啊,和業務功能不一樣的話,就會更明顯發現大問題,搶占session,無法正確請求數據
解決方案:
確立解決手段:經過測試淘寶網站發現,淘寶針對這種問題,每次操作都會刷新頁面,因為刷新頁面所有數據都將重新向后台請求,所以不會存在該問題:不刷新頁面然后通過ajax一步請求數據。所以解決手段就是只要刷新頁面全部重新請求數據就不會出現這個問題。
關鍵問題:怎么去讓瀏覽 器每次去鑒別是否為一個用戶,然后讓瀏覽器主動去刷新頁面
解決步驟:
-
- 因為問題關鍵是用戶發出的請求會被商戶的覆蓋叼,所以確認第一步在用戶每次請求的時候去檢查用戶session_id是否一致(為同一個用戶)
- 在前端每次發送ajax請求的時候去檢查每次用戶登錄的時候緩存的session_id是否和當前瀏覽器登錄的用戶使用的session_id是否一致
- 因為安全退出的時候我們會清除所有該域名下的cookie(這是我們設定的規則),然后用戶登錄更新cookie,所以cookie中無法去檢測是否一致。PS:其實在cookie中也可以判斷,每次登錄判斷oldSession_id是否有值,沒有的話就將oldSession_id和newSession_id都設置為該用戶的Session_id,安全退出的時候只清除newSession_id,用戶在新標簽頁再登錄的時候判斷oldSession_id的值,然后設置newSession_id的值。這樣就可以比對了,但是我們的規則是清除所有的cookie,所以沒辦法,這里我們走不通。
- 最后靈光一閃,想到了單頁應用的優點:不刷新頁面,從而進行局部刷新或操作。這就代表着,單頁應用每次進行dom渲染完成之后,就不會第二次渲染整個頁面的dom,也就代表了window對象不會像每次頁面刷新重置window中的方法和對象了,那么我們就可以將每次緩存當前用戶的session_id到window對象中,這樣的話,我們每次請求的時候取到每次用戶登錄緩存的session_id和及時更新的cookie中的當前用戶的session_id進行比對,如果不一樣,那么就可以刷新頁面,整個頁面重新去請求整個數據,這樣就不會出現這樣覆蓋session_id的問題
- 好了,問題解決了,但是需要注意的是,每次新開一個單頁應用頁面都要緩存一下session_id這樣很繁瑣,但是沒辦法,業務規則確定了安全退出,不留任何痕跡。繁瑣不是問題,解決問題才不是問題
其實解決問題的方式有千萬種,沒有你解決不了的,只有你想不到的。程序員的路還很漫長,如果目標更大一點,架構師啊或者其他的話,這樣的路更長。而且在職場的話,老板不是要的你的各種阻塞的理由,而是一個結果,你解決了沒有?解決了,ok能力杠杠的,解決不了,對不起,能力還欠缺。所以,我的原則是:能做的,漂亮的解決;不能做的,評估一下,想方設法去解決,這樣才能讓老板或者你的上司相信你,安心把事情給你做,這樣的話,老板器重你了,升職加薪也不是問題咯。
分享我的全棧書簽(持續集成中):https://github.com/GerryIsWarrior/MyBookmarks 希望點顆星,這才是我的動力
個人簡介:
- 性別:男
- 愛好:女
- 目標:全棧架構師
- github:https://github.com/GerryIsWarrior