Js数据劫持与数据代理

更新日期: 2019-06-06阅读: 4.8k标签: 劫持

数据劫持

数据劫持即使用Object.defineProperty()实现了vue的双向绑定。先来看看它是如何实现的

let obj = {}, txt = ''
Object.defineProperty(obj,'txt',{
    set(val) {
    
        console.log('set ....')
        txt = val || '';
    },
    get() {
        //获取obj.txt时会触发get的回调。
        console.log('get ....')
        return txt
    }
})

Object.defineProperty的缺点
1、无法监听到数组的变化
举个例子

//当被监听的属性是数组时
let arr = [1,2,3]
let obj = {}
Object.defineProperty(obj,'arr',{
    set(val) {
        console.log('set',val)
        arr = val
    },
    get() {
        console.log('get')
        return arr
    }
})
obj.arr.push(4) // get 实际上是改变arr的值但是却没有执行set而是执行了get
obj.arr = [1,2,3,4] // 执行了set

当被监听的属性是数组,这几个方法push、pop、shift、unshift、splice、sort、reverse不会触发set。vue将这几个修改原始的数组的方法称为变异方法

2、必须遍历对象的每一个属性

Object.keys(obj).forEach(key=>{
    Object.defineProperty(obj,key,{
        //....
    })
})

3、必须深层遍历嵌套对象

let person = {
    name:{
        firstName:'chan',
        lastName:'louis'
    }
}

当遇到变异方法时旧版本的vue通过重写方法来进行数据劫持

const aryMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
const arrayAugmentations = [];
aryMethods.forEach((method)=> {
  // 这里是原生 Array 的原型方法
  let original = Array.prototype[method];
  // 将 push, pop 等封装好的方法定义在对象 arrayAugmentations 的属性上
  // 注意:是实例属性而非原型属性
  arrayAugmentations[method] = function () {
    console.log('has change');
    // 调用对应的原生方法并返回结果
    return original.apply(this, arguments);
  };
});
let list = ['a', 'b', 'c'];
// 将我们要监听的数组的原型指针指向上面定义的空数组对象
// 这样就能在调用 push, pop 这些方法时走进我们刚定义的方法,多了一句 console.log
list.__proto__ = arrayAugmentations;
list.push('d');  // 我被改变啦!
// 这个 list2 是个普通的数组,所以调用 push 不会走到我们的方法里面。
let list2 = ['a', 'b', 'c'];
list2.push('d');  // 不输出内容


Proxy数据代理

proxy即代理的意思。个人理解,建立一个proxy代理对象(Proxy的实例),接受你要监听的对象和监听它的handle两个参数。当你要监听的对象发生任何改变,都会被proxy代理拦截来满足需求。

var arr = [1,2,3]
var handle = {
    //target目标对象 key属性名 receiver实际接受的对象
    get(target,key,receiver) {
        console.log(`get ${key}`)
        // Reflect相当于映射到目标对象上
        return Reflect.get(target,key,receiver)
    },
    set(target,key,value,receiver) {
        console.log(`set ${key}`)
        return Reflect.set(target,key,value,receiver)
    }
}
//arr要拦截的对象,handle定义拦截行为
var proxy = new Proxy(arr,handle)
proxy.push(4) //可以翻到控制台测试一下会打印出什么

1、使用proxy可以解决defineProperty不能监听数组的问题,避免重写数组方法;
2、不需要再遍历key。
3、Proxy handle的拦截处理器除了get、set外还支持多种拦截方式,具体请查阅官方文档(https://developer.mozilla.org...
4、嵌套查询。实际上proxy get()也是不支持嵌套查询的。解决方法:

let handler = {
  get (target, key, receiver) {
    // 递归创建并返回
    if (typeof target[key] === 'object' && target[key] !== null) {
      return new Proxy(target[key], handler)
    }
    return Reflect.get(target, key, receiver)
  }
}

链接: https://www.fly63.com/article/detial/4072

ES6 Proxy与数据劫持

随着前端界的空前繁荣,各种框架横空出世,包括各类mvvm框架百家争鸣,比如Anglar、Vue、React等等,它们最大的优点就是可以实现数据绑定,再也不需要手动进行DOM操作了,它们实现的原理也基本上是脏检查或数据劫持

使用Typescript装饰器来劫持React组件

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。 装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。

HTTPS劫持研究

HTTPS通过加密传输数据来保护浏览器和网站之间的安全交互,从而防止ISP和政府对传输进行读取和篡改。服务器通过提供由证书颁发机构(CA)进行数字签名的证书来验证自己身份,而证书颁发机构就是被浏览器信任、能担保网站身份的一个实体

网站被劫持的危害和解决办法

如何检查自己的网站是不是被劫持了?IIS7网站监控,测网站是否被劫持、DNS污染检测等信息。被劫持的网站,当打开网址的时候,会跳转到其他的网址,造成用户无法正常的访问

什么是网站劫持?

百度搜索流量事件是网站劫持的其中一种表现。网站劫持还会导致以下问题:用户输入正常网址跳转到其它地址,导致用户无法正常访问,网站流量受损;通过泛域名解析生成大量子域名共同指向其它地址,跳转到非法网站,造成网站权重降低;

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!