【问题标题】:Stop a function from execute with Chrome extension使用 Chrome 扩展程序停止执行函数
【发布时间】:2012-02-19 08:19:06
【问题描述】:

这是一个简单的页面:

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test page</title>
    <script type="text/javascript">
        function foo (num) {
            alert(num);
        }
    </script>
</head>
<body>
    Hello World
    <script type="text/javascript">
        foo(2);
    </script>
</body>
</html>  

我想写一个 Chrome 扩展来防止底部脚本的执行(foo(2))。
我试图编写一个内容脚本,删除最后一个脚本标签:

document.body.removeChild(document.body.lastChild);  

但它不起作用。

我认为这可能是因为内容脚本在最后一个脚本行执行后运行。然后我尝试将run_at 设置为document_startdocument_end,但它们都不适合我..

【问题讨论】:

  • 你尝试过覆盖 foo 吗? document.write('&lt;script&gt;function foo () {}&lt;/script&gt;');document_start 的内容脚本内?编辑:没关系,document_start 在任何其他脚本执行之前
  • @Wong2 我下面的答案现在可以工作了,因为错误是 marked as fixed

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

我在开发Don't track me Google 用户脚本/扩展时遇到了同样的问题。

#重要提示 Chrome 内容脚本中的window 对象无法以任何方式直接访问。
我测试了很多方法,only可靠的方法是通过动态创建的脚本标签注入代码。查看this answer 或我的扩展程序source code 了解更多信息。

我使用Object.defineProperty 解决了这个问题。使用此方法,您可以定义一个属性,并指定有关 getter、setter 和属性描述符的信息。在你的情况下:

Object.defineProperty(window, 'foo', {
    value: function(){/*This function cannot be overridden*/}
});

或者,如果你想捕获变量,并在以后使用它:

(function() {
    var originalFoo = function(){/*Default*/};
    Object.defineProperty(window, 'foo', {
        get: function(){
            if (confirm('function logic')) return function(){/*dummy*/};
            else return originalFoo;
        },
        set: function(fn){originalFoo = fn;}
    });
})();

##Chrome 17 中的错误 [错误 #115452](http://code.google.com/p/chromium/issues/detail?id=115452) [已修复!](http ://code.google.com/p/chromium/issues/detail?id=115452#hc4) 在 Chrome 17 中,使用 V8 3.7.12.12(但不是在 Chrome 16 中,使用 V8 3.6.6.19),**函数声明会覆盖属性描述符**。
见 http://jsfiddle.net/bHUag/
请注意,当函数声明和属性描述符方法位于同一块中时,此错误 *似乎* 不适用。不过,这是错误的。效果是不可见的,因为函数声明总是在代码块之前进行评估。因此,首先评估 `function foo(){}`,然后是其余代码。
<script>
Object.defineProperty(window, 'foo', {value: function(){return 5;} });
</script><script>
function foo(){return 1};
alert(foo()); // Shows 5 in all browsers except for Chrome v17
</script>

【讨论】:

  • 我之前尝试过类似的方法,但没有成功...Object.defineProperty (window,"foo",{ value : function(){}, writable: false }); 如果您尝试将值更改为 0,它不会改变,但如果您尝试将其重新声明为函数它会?现在尝试了您的版本和相同的问题。使用 Chrome 19.0.1041.0 在paez.kodingen.com/blockme.html 上测试(尝试阻止 foo()),是的,我将代码注入页面。
  • @PAEz 您是否将"run_at": "document_start", 添加到您的manifest.json 文件的content_scripts 部分? (link to developer's documentation)。
  • 是的。我刚刚在控制台中尝试了一些我认为很有趣的东西....输入Object.defineProperty (window,"food",{ value : function(){}, writable: false }); 然后输入food(结果,预期),然后food=3 然后food(结果,预期),现在food=function(){alert('bleh')};food(结果,预期)..但现在为了好玩function food(){alert('bleh')};food...结果,食物变了。
  • @PAEz 我们在 Chrome 的 JavaScript 实现中发现了一个错误(不需要 v8,因为该错误不会出现在 Node.js 的 REPL 中)。
  • 你可以报告这个错误;)我相信你的措辞会比我的好,我不擅长技术方面的事情。如果你这样做了,请在此处发布,以便我们为它加注星标。还覆盖过去工作的 const foo=function(){}(显然是 stackoverflow.com/questions/9246772/…)。
【解决方案2】:

我认为值得一提的是相对较新的元数据项// @unwrap,它将用户脚本从用户脚本通常运行的沙箱中取出。更多信息:

https://wiki.greasespot.net/Metadata_Block#.40unwrap

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多