使用LocalStorage、sessionStorage報異常DOMException: Failed to execute 'setItem' on 'Storage': 解決方法
阿新 • • 發佈:2019-02-20
本次專案需要用到前臺快取,使用了LocalStorage、sessionStorage
,但使用過程中報異常,原因及解決方法如下:
快取到LocalStorage
呼叫localStorage.setItem
方法儲存快取物件。一般來說,只要這一行程式碼就能完成本步驟。但是LocalStorage儲存的資料是有大小限制的!我利用
chrome 做了一個小測試,儲存500KB左右的東西就會令 Resources 面板變卡,2M 幾乎可以令到 Resources 基本卡死,到了 5M 就會超出限制,sessionStorage也是一樣的,瀏覽器丟擲異常:
at Error (native)
因此需要使用 try catch 對localStorage.setItem
/** * 把快取物件儲存到localStorage中 * @param {string} key ls的key值 * @param {object} storeObj ls的value值,快取物件,記錄著對應script的物件、有url、execute、key、data等屬性 * @returns使用sessionStorage和會和上述情況一樣,按此解決就行{boolean} 成功返回true */ var addLocalStorage =function( key, storeObj ){ // localStorage對大小是有限制的,所以要進行try catch // 500KB左右的東西儲存起來就會令到Resources變卡 // 2M左右就可以令到Resources卡死,操作不了 // 5M就到了Chrome的極限 // 超過之後會丟擲如下異常: // DOMException: Failed to execute 'setItem' on 'Storage': Setting the value of 'basket-http://file.com/ykq/wap/v3Templates/timeout/timeout/large.js' exceeded the quotatry{ localStorage.setItem( storagePrefix + key, JSON.stringify( storeObj )); return true; }catch( e ){ // localstorage容量不夠,根據儲存的時間刪除已快取到ls裡的js程式碼 if( e.name.toUpperCase().indexOf('QUOTA')>=0){ var item; var tempScripts =[]; // 先把所有的快取物件來出來,放到 tempScripts裡 for( item in localStorage ){ if( item.indexOf( storagePrefix )===0){ tempScripts.push( JSON.parse( localStorage[ item ])); } } // 如果有快取物件 if( tempScripts.length ){ // 按快取時間升序排列陣列 tempScripts.sort(function( a, b ){ return a.stamp - b.stamp; }); // 刪除快取時間最早的js basket.remove( tempScripts[0].key ); // 刪除後在再新增,利用遞迴完成 return addLocalStorage( key, storeObj ); }else{ // no files to remove. Larger than available quota // 已經沒有可以刪除的快取物件了,證明這個將要快取的目標太大了。返回undefined。 return; } }else{ // some other error // 其他的錯誤,例如JSON的解析錯誤 return; } } };