有的時候鏈接信息中存在敏感信息或者不想讓用戶手動修改鏈接從而改變內容,這時候就需要進行鏈接加密處理,雖然這種方式只能簡單的預防,不過還是能起到一定作用的,這里根據我的思路進行總結處理方式
-
首先網站頁面url都有對應的不同路徑組成,這個地方不用修改(當然也可以自己擴展),后邊可能會拼接一些參數對這串參數進行處理 ;
思路就是在頁面跳轉前進行攔截修改參數部分,及在改變頁面某些狀態需要改變url內容時進行修改參數部分;
那么頁面在重新載入或者進入時,首先需要進行對頁面的加密參數解密到對應字段上進行后邊的參數處理;
-
下邊是url加密和解密方法
/** * url參數加密 * 傳入json格式的串 * @param {*Object} query */ const EncryUrl = query => { if (!utils.isObject(query)) { return ""; } try { query = JSON.stringify(query); query = window.encodeURIComponent(query); return window.btoa(query); // 編碼 } catch (err) { console.log('%c url-encry-error:' + JSON.stringify(err), 'color:red;'); } return ""; } /** * url參數解密 * 傳入加密的json串 * @param {*string} val */ const DecryptUrl = val => { if (!utils.isString(val)) { return false; } try { let decryStr = window.atob(val); // 解碼 return window.decodeURIComponent(decryStr); } catch (err) { console.log('%c url-decry-error:' + JSON.stringify(err.stack), 'color:red;'); } return false; }
以上,加密方法EncryUrl,首先判斷傳入的數據是否是Object的,然后把json轉成字符串,使用encodeURIComponent進行URI編碼(encodeURIComponent方法執行,讓瀏覽器能夠接受和理解,若中文在使用后邊的window.btoa會報錯),然后使用window.btoa再次轉換輸出;解密DecryptUrl,以同樣的方式反過來執行進行解密,至於為什么后邊沒有使用JSON.parse,看后邊的;
/** * 從地址欄獲取指定參數值 * @param {*string} param */ const GetQueryParam = (param) => { let h = window.location.href; let reg = new RegExp("[\?\&]?" + param + "=([,-\w]+)[\&]?", "i"); if (reg.test(h)) { let v = reg.exec(h)[1]; return v; } return ""; }; /** * 返回 地址欄 加密 Object * @param {*string} param */ const GetQueryParamOfObjEntry = () => { let keyStr = GetQueryParam("key"); if (!keyStr) { return ""; } try { let objStr = DecryptUrl(keyStr); let obj = JSON.parse(objStr); return obj; } catch (err) { console.log('%c url-json-parse-error:' + JSON.stringify(err.stack), 'color:red;'); } return ""; }
上邊的兩個方法,GetQueryParam是封裝了獲取指定鏈接參數的代碼塊,GetQueryParamOfObjEntry是獲取以key這個指定參數后方的解密數據,這里可以看到有JSON.parse這個方法,因為我這里約定了鏈接后方參數是以key為key的一個參數,當然可以換成其他的參數;
-
然后注意在router里邊需要處理對應的改變
// url參數加密 function encryUrlOfRouter(to, from, next) { // 這里對路由參數key進行加密 if (Object.keys(to.query).length > 0 && !to.query.key) { let urlEntry = EncryUrl(to.query); if (urlEntry) { next({ path: to.path, query: { key: urlEntry } }) return false; } next({ path: to.path }) return false; } return true; }
以上代碼塊,encryUrlOfRouter這個方法放在router.beforeEach里邊執行,首先判斷當前鏈接是否有參數,若有且如果不存在key,那么就使用EncryUrl進行處理query加密,然后修改當前鏈接參數,這時,router會再次執行一次 ;
-
那么在頁面中使用時,首先是初次渲染拿出數據了,在created中執行時可以使用GetQueryParamOfObjEntry來獲取數據,然后對應參數賦值;
其次是在一些改變url參數的操作,(場景:比如分頁,觸發分頁后,把這個鏈接復制到其他的窗口中,既要讓參數加密,又必須讓這個鏈接打開窗口的分頁的狀態和被復制頁面的分頁一樣),這個時候在每次觸發改變鏈接的時候執行這個方法就沒問題了;
當然這時候並沒有改變頁面位置,也不會刷新頁面,只是走了一遍路由,下方代碼就是對應改變的方法了, searchCondition就是我存放需要改變url參數的對象
editUrlQuery() {
this.$router.push({ name: this.$route.name, query: this.searchCondition });
}
- 最后總結一下,如果是對安全性要求比較高在執行加密時可以換其他的方式來加密,我這里只是簡單的加密了一下,讓別人篡改參數不是那么很輕松 ,也直接看出url里邊帶的參數是什么;如果在控制台中進行解密測試,你需要執行window.decodeURIComponent這個方法兩次,why?不解釋,哈哈,實踐一下就知道了;如果別人修改了key后邊的參數,那么解析會出錯,或者解析不完全,至於修改,隨他改吧,看你的加密方式了;