前端源數據安全解決方案

對比我們的傳統行業來講,互聯網行業不得不說是一個新興的行業,無論是從他的問世時間還是人們對他的瞭解程度上都是這樣;可能有人會說了,我們天天接觸網絡,怎麼能說不理解呢?我在這裏講的瞭解的意義不僅僅指的是會用的層級上面,而是真正的瞭解它的運行原理和其他相關,最直白的講,我們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)

 

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