防止浏览器控制台修改网页数据与函数的方法(续)

        前文《防止浏览器控制台修改网页数据与函数的方法》给出了几个解决方法,需要对对象的每个属性或函数使用Object.defineProperty()配置其元特性configurable、enumerable、writable等。显然,这些操作缺乏灵活、不够实用、不能通用。

       1、javascript对象的元特性

        javascript对象的成员(数据或函数)均有一组元特性,约束成员的是否可配置(configurable)、可枚举(enumerable)、可改写(writable),以及提供value值和getter/setter读写器。一旦configurable为false,那么不能重定义其他的特性(writable除外,仍然可以由true改为false)。如果configurable为true,即使wrtiable为false,仍然可以通过Object.defineProperty()或Reflect.defineProperty()函数修改其value(此时不能通过类似obj.val = 1的方式修改其值)。

        定义或修改元特性的语法如下:

  • Object.defineProperty(obj, propName, {元特性}, value)
  • Reflect.defineProperty(obj, propName, {元特性}, value)

        Object与Reflect两个同名方法的区别在于:前者定义成功返回对象、失败抛出异常;后者成功返回true、失败返回false。另一个区别是,Reflect支持的最低版本是ES6(与Proxy一样)。

        2、保护window和对象(以String.prototype为例)上新增的属性和函数       

        ES6中的Proxy类和Reflect类提供了通用、一致的便捷方法,只需要给被保护的对象(如window对象、String.prototype原型、String构造函数等)关联一个代理对象,在代理对象上新增属性或函数,就可以自动配置其元特性{configurable: false, enumerable: true, writable: false},从而保护数据(属性值)或函数被删除或修改。

        下面代码是一个关联window对象和String.prototype原型的两个代理类,分别增加其函数sayOk(),然后修改函数定义,结果是:修改后的函数无效。




        上文的技术要点是:创建一个通用的处理器handler,并关联到一个代理Proxy对象。然后,在代理对象上添加函数,这些新增的函数将自动配置成{configurable: false, enumerable: true, writable: false}元特性,使得它们不能被删除或修改。同样,新增数据属性结果相同。

        3、保护网页元素的value值

        前文《防止浏览器控制台修改网页数据与函数的方法》提出方法时:获取该值后另存为window对象的一个不可修改的数据属性,可以有效保护该数据被删除或修改,但使用起来不够直接明了。

        下面代码可以直接保护元素的value属性,使得该值正常读取、不能被删除或修改(代码中还给出了jQuery读写的示例)。






	输入文本1: 
输入文本2:

        因为是保护已经存在的若干对象,不需要使用代理Proxy,直接使用Object.defineProperty()即可。

        需要特别指出,不同于配置一般对象的元特性,Object.defineProperty()设置value的元特性时,还需要给出value值。原因是,value不是HTMLInputElement元素的自有属性,而是其原型上继承来的属性,而Object.defineProperty()只能配置对象自有属性的元特性。事实上,上述代码在配置value元特性时,等价新建了一个对象的自有value属性(该属性隐藏了原型的value属性,相当于派生类隐藏了基类属性),在配置其元特性时需要给出并保留原value的值。

你可能感兴趣的:(防止浏览器控制台修改网页数据与函数的方法(续))