頁面間大量數據參數傳遞
前言
我們在開發項目中經常會遇到一種問題,就是在前端頁面跳轉時傳遞某些參數,通常我們是通過路由傳遞的,但是如果數據量很多的情況下,會造成路由非常的長,如果在大的話甚至會超出地址欄URL的最大限度,這就狗帶了.最近手頭上一個項目的前端剛好遇到這個問題,該項目前端用的是vue2.x.不是什麽大問題,但是之前沒有認真想過解決辦法,於是將解決思路記錄下來了.
地址欄URL最大限度
首先我查了不同瀏覽器地址欄URL的最大限度.
雖然HTTP協議的RFC規範並沒有詳細規定URL的最大字符長度限制,但實際上,在瀏覽器或者服務器中總會存在限制的。這裏所說的字符是指ASCII字符。HTTP RFC2616協議沒有規定URL的最大長度,規定服務器如果不能處理太長的URL,就得返回414狀態碼(Request-URI Too Long)。
微軟 Internet Explorer:
微軟幫助網站上說IE7之前(包括IE7)的瀏覽器,對URL的最大長度限制是2,083個字符。
Firefox:
對於Firefox1.5.x,地址欄能顯示的URL最大長度是65,536個字符,但實際上有效的URL最大長度不少於100,000個字符。
對於Firefox 3.0.5,mozilla官方論壇上有人測試其URL長度限制為65,000個字符。
也有人說Firefox可以支持URL高達2Gbyte的長度(參考),在data URL中可以運用到這樣大數據量的URL。dataURL是一種URL本身包含了實際數據的URL,比如一個圖片、一個HTML網頁或者全部的數據、代碼等等。僅有Firefox支持dataURL。
Safari:
Safari最少支持80,000個字符長度的URL。
Opera:
Opera官方網站上說,Opera並沒有強制限制URL的長度。
網友測試Opera 9支持最少190,000個字都長度的URL,並且Opera9的地址欄可以顯示、編輯、復制和粘貼完整的URL串。
綜上,又在網上找了一個附表:
IE |
URL最大限制是2083個字節,Path長度最大是2048字節(Get請求)。 |
Firefox |
65536 |
Safari |
80000以上 |
Opera |
190000字節以上 |
Chrome |
8182字節 |
Apache Server |
8192字節 |
IIS |
16384字節 |
Perl HTTP::Daemon |
至少8000字節 |
我的思路
思路一
我的第一個想法就是通過緩存進行解決----cookie/localStorage/sessionStorage.通過在服務器或客戶端進行數據緩存以供頁面進行讀取.但是在後續的思考中我想到首先cookie緩存量很小,同時session/cookie對與網站所有頁面是透明的,我只是想實現指定頁面間進行參數傳遞,其他頁面應該不知情,考慮到保密性,我放棄了這個想法.
思路二
我的第二個思路還是通過緩存來實現,但是是通過application cache(共享本地緩存),具體的介紹就不在這裏說了.但是我考慮到application cache具有緩存時間,而我想要的是在頁面跳轉後緩存的參數數據被銷毀,也就是類似閃存的機制.同時application cache緩存頁面需要的資源,那麽其他頁面所需要的資源也同時被緩存下來,這樣做得不償失.
思路三
通過js的全局變量.這個沒什麽介紹的,將參數保存在全局變量中,那麽在頁面聲明周期內所有頁面都可以使用.但是還是那個問題,在使用全局變量的時候,其他頁面也能夠獲得.所以pass.
思路四
我找到利用原生很不錯的方法,那就是通過模態窗口來實現頁面間的參數傳遞.以下是對showModalDialog(模態窗口)的簡單介紹:
基本介紹:
showModalDialog() (IE 4+ 支持) showModelessDialog() (IE 5+ 支持) window.showModalDialog() 方法用來創建一個顯示HTML內容的模態對話框。 window.showModelessDialog() 方法用來創建一個顯示HTML內容的非模態對話框。
vReturnValue = window.showModalDialog(sURL [, vArguments] [,sFeatures])
vReturnValue = window.showModelessDialog(sURL [, vArguments] [,sFeatures])
sURL -- 必選參數,類型:字符串。用來指定對話框要顯示的文檔的URL。 vArguments -- 可選參數,類型:變體。用來向對話框傳遞參數。傳遞的參數類型不限,包括數組等。對話框通過 window.dialogArguments來取得傳遞進來的參數。 sFeatures -- 可選參數,類型:字符串。用來描述對話框的外觀等信息,可以使用以下的一個或幾個,用分號“;”隔開。
1. dialogHeight: 對話框高度,不小於100px 2. dialogWidth: 對話框寬度。 3. dialogLeft: 離屏幕左的距離。 4. dialogTop: 離屏幕上的距離。 5. center: { yes | no | 1 | 0 } : 是否居中,默認yes,但仍可以指定高度和寬度。 6. help: {yes | no | 1 | 0 }: 是否顯示幫助按鈕,默認yes。 7. resizable: {yes | no | 1 | 0 } [IE5+]: 是否可被改變大小。默認no。 8. status: {yes | no | 1 | 0 } [IE5+]: 是否顯示狀態欄。默認為yes[ Modeless]或no[Modal]。 9. scroll: { yes | no | 1 | 0 | on | off }:是否顯示滾動條。默認為yes。 ...
通過vArguments來進行傳遞的。類型不限制,對於字符串類型,最大為4096個字符。也可以傳遞對象,如下:
test.html:
var obj=new Object();
obj.name="qiubinchao";
obj.tel="12345678";
window.showModalDialog(‘./testb.html‘,obj,"dialogWidth:500px;dialogHeight:550px");
window.location.href="./testb.html";
testb.html:
var obj = window.dialogArguments
console.log(window.dialogArguments);
test.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> show(); function AddNew() { if(!window.showModalDialog) { window.showModalDialog=function(url,name,option){ if(window.hasOpenWindow){ window.newWindow.focus(); } var re = new RegExp(";", "g"); var option = option.replace(re, ‘","‘); //把option轉為json字符串 var re2 = new RegExp(":", "g"); option = ‘{"‘+option.replace(re2, ‘":"‘)+‘"}‘; option = JSON.parse(option); var openOption = ‘width=‘+parseInt(option.dialogWidth)+‘,height=‘+parseInt(option.dialogHeight)+‘,left=‘+(window.screen.width-parseInt(option.dialogWidth))/2+‘,top=‘+(window.screen.height-30-parseInt(option.dialogHeight))/2; window.hasOpenWindow = true; window.newWindow = window.open(url,name,openOption); } } } function show() { var obj=new Object(); obj.name="qiubinchao"; obj.tel="12345678"; AddNew(); window.showModalDialog(‘./testb.html‘,obj,"dialogWidth:500px;dialogHeight:550px"); window.location.href="./testb.html"; } </script> </body> </html>
- 怎樣才讓在showModalDialog和showModelessDialog的超連接不彈出新窗口?
在被打開的網頁裏加上:
<base target="_self">
- 怎樣才刷新showModalDialog和showModelessDialog裏的內容?
在showModalDialog和showModelessDialog裏是不能按F5刷新的,又不能彈出菜單。這個只能依靠javascript了,以下是相關代碼:
<body onkeydown="if (event.keyCode==116){reload.click()}"> <a id="reload" href="filename.htm" style="display:none">reload...</a>
- 如何用javascript關掉showModalDialog(或showModelessDialog)打開的窗口。
<input type="button" value="關閉" onclick="window.close()">
也要配合<base target="_self">,不然會打開一個新的IE窗口,然後再關掉的。
- Math.random與showModalDialog。
當你設置的彈出網頁固定時(如上面的"modal.htm"頁面),ie很可能到臨時文件區,下載上次產生的該頁面(openPage.html),而沒有重新加載,對於動態加載的頁面來說,這樣往往產生誤會,如沒有及時更新數據,也就更不利於開發者測試。所以,你可以采用如下方式:
var strPage = “/medal.htm?random="+Math.random();
這樣每次產生的strPage是不一樣的.
但是最後我還是放棄了,因為首先我用的是vue框架,寫原生太不優雅;其次如上所示,使用模態窗口的局限性太大.
思路五
俗話說:解鈴還須系鈴人
在一籌莫展之際,我想到了vue-router中的params.上代碼:
傳參:
this.$router.push({name:‘/send/sendHome‘, params: {setStr: this.multipleSelection}});
接收參數:
let setArray = this.$route.params.setStr;
query傳遞參數:
傳參:
this.$router.push({
path:‘/xxx‘
query:{
id:id
}
})
接收參數:
this.$route.query.id
註意:無論是params還是query進行參數傳遞,傳參是this.$router,接收參數是this.$route,一定要細心.
區別:
1.當使用query進行參數傳遞時,參數會跟在路徑後面.我們可以在地址欄看到後面跟的參數,而params不會在地址欄顯示.直白的說query相當於get請求,而params相當於post請求.
2.params傳參,push裏面只能是 name:‘xxxx‘,不能是path:‘/xxx‘,因為params只能用name來引入路由,如果這裏寫成了path,接收參數頁面會是undefined.
果然...自己挖的坑還要自己填...
頁面間大量數據參數傳遞