我的一位客户问他们是否可以添加一些JavaScript来跟踪他们网站的用户行为。乍一看,我担心它会干扰网站上的其他第三方分析脚本,因为看起来双方都使用了相同的JavaScript压缩器。我不想梳理并搜索所有可能的命名冲突。 。
有没有办法可以包含第三方脚本(位于单独域中的脚本文件),但将它们包装在自己的命名空间中,或者为它们提供自己的范围,这样它们就不会与其他全局声明的变量和函数发生冲突?
答案 0 :(得分:4)
为了隔离:
这取决于第三方脚本,但我通常倾向于#2。可以进行交互,但是你不会受到偶然的document.write使用和全局命名空间污染的影响。
编辑:#2
的示例 page.html中的
<div>...Your content...</div>
<iframe src="tracker.html"
width="10" height="10"
style="position:absolute; top:-100px"></iframe>
tracker.html(可选择全部)
<script src="http://example.com/tracker.js"></script>
这是基本结构,但需要更多设置,否则所有流量似乎都来自tracker.html。对于跟踪脚本,我建议将查询字符串中的顶级(真实)页面路径提供给iframe:“tracker.html?u = thispage.html”。您可以在服务器端或通过javascript设置查询字符串:
page.html(再次)
<div>...Your content...</div>
<script>
(function(){
var iframe = document.createElement('iframe');
iframe.src = 'tracker.html?u=' + escape(location.href);
iframe.width = iframe.height = 1;
iframe.style.position = 'absolute';
iframe.style.top = '-100px';
var nodes = document.getElementsByTagName('script');
var s = nodes[nodes.length - 1];
s.parentNode.insertBefore(iframe, s);
})();
</script>
如果路径足以进行跟踪,您可以选择使用location.pathname而不是location.href(具有协议,域等)。
毕竟...如果跟踪脚本来自信誉良好的来源(StatCounter,Google Analytics等),我建议相信他们不要踩到你的页面变量和函数。选项1和2实际上适用于低信任情况。
答案 1 :(得分:3)
像这样:
(function() {
// insert code here
})();
享受;)
答案 2 :(得分:2)
这应该不是问题。 Javascript压缩器不重命名全局变量(出于显而易见的原因),任何设计良好的脚本都不会暴露许多(任何)全局变量。如果他们希望您将其部署在您的页面上,他们有责任防止冲突。
答案 3 :(得分:1)
这取决于你想要做什么。
1)您希望以确定不会破坏脚本的方式加载页面中的第三方脚本。
你不能在这里做很多事 要求第三方做干净的脚本....一般情况下不太可能 在iframe中加载脚本....可能会使脚本无效
可能有办法,但这可能是愚蠢的:
通过ajax加载脚本(可能需要代理以避免跨域),用脚本内容(new Function('The content of the script');
)创建一个JS函数,然后执行该函数(你也可以使用eval ...它是相同)。
这样,您可以管理为函数提供的参数,这样就可以保护全局变量。
这样做可能是打破第三方脚本的好方法。它会保护你吗?......也许吧。
无论如何,您还应该保护您免受第三方脚本的限制。每当您尝试使用在第三方脚本中声明的变量时,请始终检查是否已定义变量以确保脚本已加载。
2)您希望以不会被任何第三方脚本破坏的方式对脚本进行编码
首先:全局变量很危险。 你不知道是谁创造了它们,你不知道是谁修改了它们......不要相信它们。
您可以信任一个变量:全局范围内的this关键字。它应该是窗口对象,这个对象应该受到一点保护(至少应该是一个常量)。
如果你必须创建数组,字符串,regExp ...尽量不要使用“new Something()
”的方式来做到这一点
var myArray = []; // not new Array();
var myRegExp = /^myRegExp$/; // not new RegExp('^myRegExp$');
var myString = 'myString'; // not new String('myString');
例如,可以覆盖Array变量。如果你使用[],你不会介意。
在某些情况下,你当然不能采取其他方式,但尽量不要这样做。
由于您不能信任全局变量,您还应该避免创建一些变量。仅创建绝对必要的全局变量。其他一切都应该是本地的。如果您的脚本不那么具有侵入性,那么其他人也可能尝试这样做。
要执行此操作(主要使用局部变量),您应该在“受保护区域”中工作。一个很好的方法是匿名自动执行功能。
(function () {
// Your code here
}());
您还可以将全局变量传递给此“基本函数”。这可以有利于缩小和保护。您还可以获取“未定义”变量作为检查变量是否已定义的参考。
(function (window, alert, Array, undef) {
// Your code here
alert('I\'m safe here.');
if([] instanceof Array) {
alert('I\'ve got the real Array object');
}
if(window.jQuery === undef) {
alert('jQuery not loaded');
}
}(this, this.alert, this.Array));
我认为这样你的脚本应该受到一点保护。可能还有其他我忘记的事情,但这是一个好的开始。