前端源数据安全解决方案

对比我们的传统行业来讲,互联网行业不得不说是一个新兴的行业,无论是从他的问世时间还是人们对他的了解程度上都是这样;可能有人会说了,我们天天接触网络,怎么能说不理解呢?我在这里讲的了解的意义不仅仅指的是会用的层级上面,而是真正的了解它的运行原理和其他相关,最直白的讲,我们IT从业者可能才是最了解它的那一个群体;

下面这个方案是为了保护源数据而设计的一套方案;在保证源数据不被污染泄漏的情况下;依然可以有效的完成数据的传递和组合展示;

  • 方案一:使用Object.freeze(obj)将源数据冻结

我们可以通过Object.getOwnPropertyDescriptors()发现对象属性修饰符的变化如下:

let AH = {
  name: '杭州安恒信息技术股份有限公司',
  number: 688023,
}
console.log(Object.getOwnPropertyDescriptors(AH), '冻结前')
//冻结前
// {
//   name: {
//     value: '杭州安恒信息技术股份有限公司',
//     writable: true,
//     enumerable: true,
//     Configurable: true,
//   },
//   number: {
//     value: 688023,
//     writable: true,
//     enumerable: true,
//     Configurable: true,
//   },
// }
Object.freeze(AH)
console.log(Object.getOwnPropertyDescriptors(AH), '冻结后')
// 冻结后
// {
//   name: {
//     value: '杭州安恒信息技术股份有限公司',
//     writable: false,
//     enumerable: true,
//     Configurable: false,
//   },
//   number: {
//     value: 688023,
//     writable: false,
//     enumerable: true,
//     Configurable: false,
//   },
// }

//测试修改
AH.name='安恒信息'
console.log(AH.name) //杭州安恒信息技术股份有限公司
  • 方案二:通过枚举和Object.defineProperty(obj, prop, descriptor)直接在一个对象上定义一个新属性,或者修改一个对象的现有属性;
let AH = {
  name: '杭州安恒信息技术股份有限公司',
  number: 688023,
}
//当writable:true
for (let [key] of Object.entries(AH)) {
  Object.defineProperty(AH, key, {
    writable: true,
  })
}
AH.number = 123456
console.log(AH.name, AH.number) //杭州安恒信息技术股份有限公司 123456

let AH = {
  name: '杭州安恒信息技术股份有限公司',
  number: 688023,
}
//writable: false
for (let [key] of Object.entries(AH)) {
  Object.defineProperty(AH, key, {
    writable: false,
  })
}
AH.number = 123456
console.log(AH.name, AH.number) //杭州安恒信息技术股份有限公司 688023
  • 方案三:通过Proxy的自定义行为如属性查找、赋值、枚举、函数调用等)来完成。
let AH = {
  name: '杭州安恒信息技术股份有限公司',
  number: 688023,
  price: 228,
}
let datas = new Proxy(AH, {
  get(target, key) {
    return target[key] || ''
  },
  set(target, key, value) {
    if (Reflect.has(target, key)) {
      if (key === 'price') {
        if (value > 300 || value < 200) {
          return false
        } else {
          target[key] = value
        }
      } else {
        target[key] = value
      }
    } else {
      return false
    }
  },
})
datas.price = 100
console.log(datas.price, datas.name) //228 "杭州安恒信息技术股份有限公司"
datas.price = 288
console.log(datas.price, datas.name) //288 "杭州安恒信息技术股份有限公司"
datas.address = '浙江省杭州市滨江区西兴街道联慧街188号'
console.log(datas.price, datas.name, datas.address) //288 "杭州安恒信息技术股份有限公司" ""

另一种解耦写法,可封装利用,针对不同数据的代理逻辑都可以写在validator中

let AH = {
  name: '杭州安恒信息技术股份有限公司',
  number: 688023,
  price: 228,
}
let validator = (target, key, value) => {
    if (Reflect.has(target, key)) {
      if (key === 'price') {
        if (value > 300 || value < 200) {
          return false
        } else {
          target[key] = value
        }
      } else {
        target[key] = value
      }
    } else {
      return false
    }
  }
let datas = new Proxy(AH, {
  get(target, key) {
    return target[key] || ''
  },
  set:validator
})
datas.price = 100
console.log(datas.price, datas.name) //228 "杭州安恒信息技术股份有限公司"
datas.price = 288
console.log(datas.price, datas.name) //288 "杭州安恒信息技术股份有限公司"
datas.address = '浙江省杭州市滨江区西兴街道联慧街188号'
console.log(datas.price, datas.name, datas.address) //288 "杭州安恒信息技术股份有限公司" ""

错误上报机制代码:

// 监听错误
window.addEventListener =
  ('error',
  (e) => {
    console.log(e.message)
    // report('./') //上报逻辑写在此处
  },
  true)
let AH = {
  name: '杭州安恒信息技术股份有限公司',
  number: 688023,
  price: 228,
}
// 校验规则
let validator = (target, key, value) => {
    if (Reflect.has(target, key)) {
      if (key === 'price') {
        if (value > 300 || value < 200) {
            // 不满足规则就要触发错误
            throw new TypeError('price的价格不在可控范围内')
            // return false
        } else {
          target[key] = value
        }
      } else {
        target[key] = value
      }
    } else {
      return false
    }
  }
let datas = new Proxy(AH, {
  get(target, key) {
    return target[key] || ''
  },
  set:validator
})
datas.price = 100
console.log(datas.price, datas.name) //228 "杭州安恒信息技术股份有限公司"
datas.price = 288
console.log(datas.price, datas.name) //288 "杭州安恒信息技术股份有限公司"
datas.address = '浙江省杭州市滨江区西兴街道联慧街188号'
console.log(datas.price, datas.name, datas.address) //288 "杭州安恒信息技术股份有限公司" ""
datas.price = 888
console.log(datas.price, datas.name) //Uncaught TypeError: price的价格不在可控范围内

如果某个组建中的数据出现了问题,如何捕获,在基于上述基础上,还可以有以下的方案:

通过proxy实现“阅后即焚”的数据实例:

let AH = {
  name: '杭州安恒信息技术股份有限公司',
  number: 688023,
  price: 228,
}
let datas = Proxy.revocable(AH, {
  get(target, key) {
    if (key === 'price') {
      return target[key] + 100
    } else {
      return target[key]
    }
  },
})
console.log(datas.proxy.price, datas)
setTimeout(function () {
  datas.revoke() //撤销代理操作
  setTimeout(function () {
    console.log(datas.proxy.price)
  }, 1000)
}, 1000)

通过proxy生成id :随机性,唯一性,只读性

class Component {
  constructor() {
    this.proxy = new Proxy(
      {
        id: Math.random().toString(36).slice(-8),//生成随机数转为36进制截取后8位
      },
      {} //数据透传
    )
  }
  get id() {
    return this.proxy.id 
  }
}
let com = new Component()
let com2 = new Component()
com.id = 'abc'
console.log(com.id, com2.id)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章