vue-router路由中对query中的参数进行加密
源码地址在文末
在创建路由的时候,添加两个方法
-
stringifyQuery: 序列化传入的query参数,方法可以接收一个对象参数
在
new Router 的时候传递这个属性,在序列化query 参数的就执行这个方法,不会执行默认的方法,序列化后在地址栏显示序列化之后的参数 -
parseQuery: 解析地址栏参数,方法接收一个字符串参数
在
new Router 的时候传递这个属性,在解析query 参数的时候,回执行这个方法,不会在执行默认的方法,注: 这个方法只解析
path 中的参数,或者浏览器刷新的时候的地址栏的参数,不会对在query 参数对处理,如:1
2
3
4
5
6
7
8```javascript
this.$router.push({
path: "foo?a=123",
query: {
b: 345
}
})
```在执行这段代码的时候,
parseQuery 方法不会对query:{b: 345} 进行解析,会解析path:"foo?a=123" 中的a=123 的字符串
使用方式:
例:
- router/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import Vue from "vue" import VueRouter from "vue-router"; import { stringifyQuery, parseQuery } from "./utils/query"; Vue.use(VueRouter); const routes = [ { path: "/", name: "home", component: () => import(/* webpackChunkName: "home" */"../views/Home") }, { path: "/foo", name: "foo", component: () => import(/* webpackChunkName: "foo" */"../views/Foo") }, { path: "/bar", name: "bar", component: () => import(/* webpackChunkName: "bar" */"../views/Bar") } ]; const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, stringifyQuery: stringifyQuery, parseQuery: parseQuery, routes }); export default router |
- router/utils/query.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import { getEncryptToBase64 as encrypt, getDecryptByBase64 as decrypt } from "./encryption" const encodeReserveRE = /[!'()*]/g const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16) const commaRE = /%2C/g const encode = str => encodeURIComponent(str) .replace(encodeReserveRE, encodeReserveReplacer) .replace(commaRE, ',') const decode = decodeURIComponent /** * 序列化对象 并加密 * @param {Object} obj */ export const stringifyQuery = obj => { // 序列化方法使用的vue-router中的原方法,详见vue-router/src/query.js // 唯一的修改时最后返回的时候,对参数进行了加密 const res = obj ? Object.keys(obj).map(key => { const val = obj[key] if (val === undefined) { return '' } if (val === null) { return encode(key) } if (Array.isArray(val)) { const result = [] val.forEach(val2 => { if (val2 === undefined) { return } if (val2 === null) { result.push(encode(key)) } else { result.push(encode(key) + '=' + encode(val2)) } }) return result.join('&') } return encode(key) + '=' + encode(val) }).filter(x => x.length > 0).join('&') : null return res ? `?${encrypt(res)}` : '' } /** * 解密 解析 字符串参数 * @param {String}} query */ export const parseQuery = query => { // 先对query进行解密 // 在使用vue-router中的解析方法对query进行解析,详见vue-router/src/query.js const res = {} query = query.trim().replace(/^(\?|#|&)/, '') if (!query) { return res } // 解密 query = decrypt(query); query.split('&').forEach(param => { const parts = param.replace(/\+/g, ' ').split('=') const key = decode(parts.shift()) const val = parts.length > 0 ? decode(parts.join('=')) : null if (res[key] === undefined) { res[key] = val } else if (Array.isArray(res[key])) { res[key].push(val) } else { res[key] = [res[key], val] } }) return res } |
- router/utils/encryption.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* * 默认在html已经引入了 crypto-js.js 文件 * 加密 解密 */ const baseCryptoCode = "这一段文字用来做给路由加密的私钥"; // 私钥自己指定 const getKeyHex = cryptoCode => CryptoJS.enc.Latin1.parse(cryptoCode || baseCryptoCode); const getIvHex = () => CryptoJS.enc.Latin1.parse(baseCryptoCode); /** * 加密 * @param {String} key * @param {String} cryptoCode * @returns {string} */ export const getEncrypt = (key, cryptoCode) => { let keyHex = getKeyHex(cryptoCode); let ivHex = getIvHex(); try { key = JSON.stringify(key); } catch (e) { console.warn(e); } return CryptoJS.AES.encrypt(key, keyHex, { mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding, iv: ivHex }).toString(); } export const getEncryptToBase64 = (key, cryptoCode) => { let encryptStr = getEncrypt(key, cryptoCode); let wordArray = CryptoJS.enc.Utf8.parse(encryptStr); return CryptoJS.enc.Base64.stringify(wordArray); } /** * 解密 * @param data * @returns {string} */ export const getDecrypt = data => { let keyHex = getKeyHex(); let ivHex = getIvHex(); let decrypted = CryptoJS.AES.decrypt({ ciphertext: CryptoJS.enc.Base64.parse(data) }, keyHex, { mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding, iv: ivHex }).toString(CryptoJS.enc.Utf8); try { decrypted = JSON.parse(decrypted); } catch (e) { console.warn(e); } return decrypted } /** * 对base64数据解密 先解析base64,在做解密 * @param {String} data * @returns {string} */ export const getDecryptByBase64 = data => { let parsedWordArray = CryptoJS.enc.Base64.parse(data); let decryptStr = parsedWordArray.toString(CryptoJS.enc.Utf8); return getDecrypt(decryptStr); } |
效果:
执行:
1 2 3 4 5 6 | this.$router.push({ path: "/foo", query: { foo: "App-Foo" } }) |
地址栏:
1 | http://localhost:8081/foo?c3p1R2tZK1AvVENKZTZHRzh3TFhpUT09 |
在刷新后解析的query
1 | {foo: "App-Foo"} |
github地址:https://github.com/wukang0718/vueRouterEncryption