客户端的&LT动态删除;脚本>标签上述< HEAD> [英] Client-Side Dynamic Removal of <script> Tags in <head>

查看:146
本文介绍了客户端的&LT动态删除;脚本>标签上述< HEAD>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以删除脚本标签< HEAD> HTML文档的客户端和之前的这些标签的执行

Is it possible to remove script tags in the <head> of an HTML document client-side and prior to execution of those tags?

在服务器端,我能够插入&LT;脚本&GT; 上述所有其他&LT;脚本&GT; 标签中的&LT; HEAD&GT; ,除一人外,我想是能够去除所有后续的脚本。我没有的删除能力&LT;脚本方式&gt; 标记从服务器端

On the server-side I am able to insert a <script> above all other <script> tags in the <head>, except one, and I would like to be able to remove all subsequent scripts. I do not have the ability to remove <script> tags from the server side.

(function (c,h) {
  var i, s = h.getElementsByTagName('script');
  c.log("Num scripts: " + s.length);
  i = s.length - 1;
  while(i > 1) {
    h.removeChild(s[i]);
    i -= 1;
  }
})(console, document.head);

然而,脚本的记录数出来只有1,因为(作为@ryan指出)被之前的DOM准备好执行code。虽然在的document.ready 事件回调包装上面的code未使&LT数量的正确计算;脚本&GT; 标记中的&LT;头方式&gt; ,等到DOM准备加载失败prevent脚本

However, the logged number of scripts comes out to only 1, since (as @ryan pointed out) the code is being executed prior to the DOM being ready. Although wrapping the code above in a document.ready event callback does enable proper calculation of the number of <script> tags in the <head>, waiting until the DOM is ready fails to prevent the scripts from loading.

有没有在HTML前的DOM准备好操作的可靠手段?

如果您想了解更多的背景下,这是企图巩固的脚本,让服务器端聚集没有选项可用的一部分。许多JS库被装载的是从CMS配置选项有限。内容大多是静态的,所以有关手动聚合中的JavaScript,并从不同的位置服务是非常小的关注。替代适用的聚合技术的任何建议也将受到欢迎。

If you want more context, this is part of an attempt to consolidate scripts where no option for server-side aggregation is available. Many of the JS libraries being loaded are from a CMS with limited configuration options. The content is mostly static, so there is very little concern about manually aggregating the JavaScript and serving it from a different location. Any suggestions for alternative applicable aggregation techniques would also be welcome.

推荐答案

既然你不能prevent未来&LT;脚本&GT; 从评估标签(每当&LT; / SCRIPT&GT; 标记已被发现,&LT相应的code;脚本&GT; 是获取和评估。 &LT;脚本的src&GT; 将进一步加载到源块的文档,除非异步属性设置为获取) ,采用不同的方法需要采取。结果
之前我present解决方案,请问:有什么可以prevent脚本中的&LT;脚本&GT; 从执行标签?事实上,

Since you cannot prevent future <script> tags from evaluating (whenever the </script> tag has been found, the corresponding code of <script> is fetched and evaluated. <script src> will block a document from loading further till the source is fetched unless the async attribute is set), a different approach need to be taken.
Before I present the solution, I ask: What can prevent a script within a <script> tag from executing? Indeed,


  1. &LT的去除;脚本方式&gt;从源头code

  2. 添加内容安全策略指令,阻止来自某些来源的脚本。

  3. 触发一个(运行时)错误。

  1. Removal of <script> from the source code.
  2. Adding a Content Security policy directive to block scripts from certain sources.
  3. Triggering a (runtime) error.

1是显而易见的,和2可以从文档中得到,所以我会集中在3下面的例子是显而易见的,并且需要调整的实际使用情况。

1 is obvious, and 2 can be derived from the documentation, so I'll focus on 3. The examples below are obvious, and need to be adjusted for real-world use cases.

下面是进行代理现有方法的一般模式:

Here's a general pattern for proxying existing methods:

(function(Math) {
   var original_method = Math.random;
   Math.random = function() {
       // use arguments.callee to read source code of caller function
       if (/somepattern/.test(arguments.callee.caller)) {
           Math.random = original_method; // Restore (run once)
           throw 'Prevented execution!';
       }
       return random.apply(this, arguments); // Generic method proxy
   };
})(Math);
// Demo:
function ok()    { return Math.random(); }
function notok() { var somepattern; return Math.random(); }

在这个例子中,code阻滞剂只运行一次。您可以删除恢复线路,或添加 VAR计数器= 0; 如果(++计数器&GT; 1337) 1337后的呼叫恢复方法。

In this example, the code-blocker runs only once. You can remove the restoration line, or add var counter=0; and if(++counter > 1337) to restore the method after 1337 calls.

arguments.callee.caller 如果调用者不是函数(如顶级code)。不是一场灾难,您可以从参数或这个关键字,或任何其他环境变量看,以确定是否执行必须停止。结果
演示: http://jsfiddle.net/qFnMX/

arguments.callee.caller is null if the caller is not a function (eg. top-level code). Not a disaster, you can read from the arguments or the this keyword, or any other environment variable to determine whether the execution must be stopped.
Demo: http://jsfiddle.net/qFnMX/

下面是打破制定者的一般模式:

Here's a general pattern for breaking setters:

Object.defineProperty(window, 'undefinable', {set:function(){}});
/*fail*/ function undefinable() {} // or window.undefinable = function(){};

演示: http://jsfiddle.net/qFnMX/2/

和干将,当然:

(function() {
    var actualValue;
    Object.defineProperty(window, 'unreadable', {
        set: function(value) {
            // Allow all setters for example
            actualValue = value;
        },
        get: function() {
            if (/somepattern/.test(arguments.callee.caller)) {
                // Restore, by deleting the property, then assigning value:
                delete window.unreadable;
                window.unreadable = actualValue;
                throw 'Prevented execution!';
            }
            return actualValue;
        },
        configurable: true // Allow re-definition of property descriptor
    });
})();
function notok() {var somepattern = window.unreadable; }
// Now OK, because 
function nowok() {var somepattern = window.unreadable; }
function ok()    {return unreadable;}

演示: http://jsfiddle.net/qFnMX/4/

等。看你要阻止脚本的来源$ C ​​$ C,你应该能够创建一个脚本特定的(甚至通用)脚本破格局。

And so on. Look in the source code of the scripts you want to block, and you should be able to create a script-specific (or even generic) script-breaking pattern.

错误触发方法唯一的缺点是误差在控制台登录。对于普通用户来说,这不应该在所有有问题。

The only downside of the error-triggering method is that the error is logged in the console. For normal users, this should not be a problem at all.

这篇关于客户端的&LT动态删除;脚本&GT;标签上述&lt; HEAD&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆