javascript - 测试导航器属性是否被 getter 函数覆盖的可靠方法

标签 javascript

使用脚本可以覆盖 Chrome 和 Firefox 中的 navigator.plugins 属性

Object.defineProperty(navigator, 'plugins', {
    get: function() {
        return [1, 2, 3, 4, 5];
    },
});

所以基本上该属性是只读的,但是使用 getter 函数可以覆盖它。 (不是在控制台中,而是在脚本中)那么我如何测试该属性是否已被覆盖?

我读到有关接收应该返回 [native code] 的函数的 toString 属性

function isNative(fn) {
    return (/\{\s*\[native code\]\s*\}/).test('' + fn);
}

现在我的问题是:如何测试 getter 是否被上面的 get:function().. 覆盖?

最佳答案

有一些技巧可以让您更接近确定函数是否被覆盖:

  • 至少在 Chrome 中,plugins 存在于 Navigator.prototype 上,而不是 window.navigator 上。如果代码在 Chrome 中运行并且该属性直接在 navigator 上,则它已被覆盖。
const definitelyPatched = navigator.hasOwnProperty('plugins');
  • 如果该属性已放在原型(prototype)上,请检查属性描述符是否与默认值匹配:它应该是可枚举和可配置的。如果不是,则已被覆盖。
const descriptor = Object.getOwnPropertyDescriptor(Navigator.prototype, 'plugins');
const definitelyPatched = descriptor.set || !descriptor.enumerable || descriptor.configurable;
  • 结合以上内容,一个几乎万无一失的方法是使用 Function.prototype.toString.call< 绕过修补函数的自定义 toString/:

const fn = function() {
  return [1, 2, 3, 4, 5];
};
fn.toString = function() {
  return '[native code]';
};

Object.defineProperty(Navigator.prototype, 'plugins',
  {
      get: fn,
});

const descriptor = Object.getOwnPropertyDescriptor(Navigator.prototype, 'plugins');
console.log(Function.prototype.toString.call(descriptor.get));

只有当 Function.prototype.toString 也被覆盖时才会失败,并且可以检测到此类修补 in multi-realm environments .

关于javascript - 测试导航器属性是否被 getter 函数覆盖的可靠方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65113798/

相关文章:

javascript - hashbang vs hijax

javascript - 使用 javascript 的 Function.prototype.bind() 测试变量是否是特定的绑定(bind)函数

javascript - Objective C 检查网页 View 中是否存在元素

javascript - 为什么 react-select 的菜单选择的 setState 使模态关闭状态?

javascript - 使用jQuery animate向左滑动时保留css float

javascript - 输入不起作用的功能

javascript - 基于 URL 管理 JSON 数据的专业/最佳方法是什么?

javascript - JQuery 类选择器在 removeClass 之后仍然触发

javascript - Jquery '$' 未定义

javascript - 如何使用 javascript 调用代码隐藏函数?