客户端的&LT动态删除;脚本&GT;标签上述&lt; HEAD&GT; [英] Client-Side Dynamic Removal of <script> Tags in <head>
问题描述
是否可以删除脚本标签&LT; HEAD&GT;
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,
-
&LT的去除;脚本方式&gt;从源头code
- 添加内容安全策略指令,阻止来自某些来源的脚本。
- 触发一个(运行时)错误。
- Removal of
<script>
from the source code. - Adding a Content Security policy directive to block scripts from certain sources.
- 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屋!