需求是這樣的:需要統計用戶公司某款產品用戶的回饋情況,美工給的設計多個psd,每個頁面里面都有一個選擇題,讓用戶選擇自己的答案,最后經過幾次選擇之后在最后一個頁面統一提交到后台!所以這里引出的技術需求就是:如何在每個頁面之間實現數據共享,比如用戶進入下個選擇頁面之后怎么保存用戶在上一個頁面選擇的數據,以便最后統一提交,因為這個項目比較獨立,而且也只是簡單的幾個頁面做統計需求,所以我並沒有采用angularjs來搭建項目,所以沒有用angular里面路由帶參數的形式來向下一個頁面傳遞數據,但是我這里使用的方法原理其實是一樣的!
首先說一下當時想到的幾個解決方法:1、每次用戶在上一個頁面選擇之后,用localStorage/sessionStorage來保存用戶的選擇;2、使用cookie來保存用戶選擇,然后在后面的頁面獲取cookie來實現共享數據;3、使用url來實現傳遞數據,類似發送get請求的把數據帶在url查詢參數里;4、不要做成多個頁面的形式,而是做成一個大頁面,采用javascript控制某些“頁面”的顯示/隱藏的方式來模擬多頁面形式,同時通過閉包實現保存用戶提交的數據!
最后我采用了url的形式來實現保存數據,我后面會說一下為什么會選擇這種方式,以及會說明其它方法為什么不適合在這里使用!當然了,這里我寫這篇文檔的目的除了要記錄自己在實現這個需求的一些所思所想以外,因為上面的需求都是介於同一個服務器上的數據共享,沒有出現跨域相關的問題,所以我還想對跨域時候發生數據共享問題及解決方法作統計記錄,所以本文檔將分為兩個部分:同域實現數據共享和跨域數據共享,同域部分就以上面這個例子為例說明,跨域部分則會自由、發散說明!
同域部分實現數據共享
采用localStorage/sessionStorage來保存數據
-
首先說一下原理,localStorage/sessionStorage都是一個本地存儲數據接口,它們兩的用法都差不多的,唯一的區別就是在保存時效上:localStorage是永久保存的本地的,除非你主動清空瀏覽器本地數據,否則即使你關閉瀏覽器重啟,數據照樣保存在哪里,而sessionStorage也是持久保存數據的,但是它在瀏覽器當前窗口關閉之后再重啟的時候保存的數據會清空就!
-
對於這兩個接口,你只要記住它們主要的兩個方法就好了,如下:
localStorage.setItem('localData','localStorage test data');//設置數據 var localData = localStorage.getItem('localData');//取出數據 sessionStorage.setItem('sessionData','session test data');//設置數據 var sessionData = sessionStorage.getItem('sessionData');//取出數據
- 此時我們打開chrome瀏覽器控制台resources選項,相關數據截圖如下:
- 好了說一下,如果使用這兩個方法實現數據共享的話,思路就是,每次用戶選擇完成的時候,用localStorage/sessionStorage保存當前的數據,最后在提交的頁面獲取全部數據,然后提交到后台!理論上這樣做是沒有問題的,但是我想了一下在這里不適合用這種方式。因為這個兩個接口保存的數據都是永久性保存的,也就是說用戶第一次選擇好選項之后,然后沒有提交,而關閉了頁面,但是他第二次直接進入最后提交的那個頁面,而此時用戶本來是想改它之前選擇的選項的,可是這里沒有提示,用戶就直接提交了!所以這里有點業務邏輯不行!當然了,也可以采用js告訴瀏覽器,在用戶最后關閉瀏覽器的時候清空相關數據,代碼如下:
localStorage.removeItem('localData');//刪除數據 sessionStorage.removeItem('sessionData');//刪除數據
- 個人覺得,localStorage/sessionStorage適合保存那種在較九不需要修改的數據信息,比如用戶登陸網站的配置信息等!而不適合保存一次性數據!
采用cookie保存數據
- cookie也是一種客戶端在本地保存數據的方式,設置方式如下:
document.cookie = "cookieData='cookie test data'";//設置cookie document.cookie;//獲取所有cookie (function(){ //獲取某一個cookie function getCookie(cookieName){ var regexp = new RegExp("(;?|^)"+cookieName+"=([^;]*)(;|$)","mi"); var arr = document.cookie.match(regexp); console.log(arr); return arr[2]; }; })();
chrome瀏覽器控制台截圖如下:
刪除cookie只需要給某個cookie設置一個過期時間就可以了,比如我設置上面的cookieData,只需要像下面這樣做一下就可以輕松實現刪除cookie:
var nowTime = new Date().getTime();//獲取當前時間 var expirAtionTime = new Date(nowTime-1);//設置過去時間 document.cookie = "cookieData='cookie test data';expires="+expirAtionTime.toGMTString();
控制台截圖如下:
當然了,cookie還可以設置很多其它參數,比如安全域、主機等,總之我的理解就是cookie和localStorage/sessionStorage是差不多的數據存儲方式,只是cookie更靈活一點,但設置起來要難一點!
雖然我剛開始是想使用cookie來實現上面的需求,但我后來發現cookie除了存在跟localStorage/sessionStorage一樣的問題以外,保存的數據在用戶退出重進不能很好的更新,還存在兼容性,在移動端有的瀏覽器存在不支持cookie,(注:cookie在移動端什么情況,在這里不深究!具體可自行查閱相關資料!)所以這種方式被終止!
通過URL方式來保存數據
- 這種方式就是通過給url帶參數和查詢的方式來實現傳遞、共享數據,如要在a頁面跳到b頁面實現向b頁面傳送testData可以像下面那樣實現:
<!--a頁面--> <a href="./b.html?shareData=testData">鏈接b</a> <!--b頁面--> <script type="text/javascript"> var data = location.search.slice(1).split('&')[0].replace('shareData=','');//testData </script>
我這里就采用了這種方式,因為采用url的方式傳輸數據不會存在localStorage/sessionStorage、cookie發現的問題,但是這種方式也有它不好的地方,因為url不能傳輸太大的數據,有字節數顯示,當然了我結合這個需求的實際情況,我覺得這里可以采用這種方法。
采用閉包方式實現保存數據
- 這種方式的原理就是模擬一個選項卡的點擊切換的效果來實現多頁面的需要,但實際上是一個頁面,同時在全局保存一個變量用來存儲將來要提交的數據,這種方式不會存在前面的提到的一些問題,數據是臨時的,能很好的即時刷新。但集合實際情況我沒有選擇在這里使用這種方式來時間保存數據,因為這回使得html、css、javascript耦合太強了,將來如果需求要改的話,很不靈活,所以終止!
注:這里不討論worker方式
跨域方式實現數據共享
- 因為這里沒有案例參考,那我們自由發揮吧,想到哪里就講到哪里!其實同域和跨域代碼在主要邏輯什么沒有什么不同,就是跨域多了一層跨域的處理,所以我們這里說下怎么實現跨域就好,因為其它的邏輯還是原來同域的那個部分!那我們說下怎么解決跨域問題。
_ 1、使用cors:
這種方法的好處就是你根本不用改變你前台的寫的代碼,你同域的時候怎么寫的,現在跨域就怎么寫,只是需要在后台服務器端響應的時候配置一下"Access-Control-Allow-Origin"響應頭就好,把它的設置成你允許訪問的那個服務器就好,就是你想獲取數據的那個頁面所在的服務器。可以設置*,這樣所有服務器都可以訪問這個資源了。
_ 2、使用jsonp
_ 3、使用代理服務器
理解這種方法的前提是首先需要知道為什么會出現跨域問題?因為瀏覽器有個同源策略,所以才會出現跨域問題,那么我們把數據放在后台去請求呢!問題就會迎刃而解了,因為服務器端是沒有同源策略的!
_ 4、其它方式
還有其他的方式,比如frame、postMessage等




