Javascript 是否有任何方法可以防止重写单例实例中的函数/变量?
考虑以下伪代码:Javascript 是否有任何方法可以防止重写单例实例中的函数/变量?,javascript,singleton,javascript-objects,overwrite,Javascript,Singleton,Javascript Objects,Overwrite,考虑以下伪代码: (功能(窗口){ var options={/*一切都在哪里*/}; 变量实例=(函数(选项){ 对于(选项中的var i){ if(选项.自有财产(i)){ 此[i]=选项[i]; } } })(可选方案); instance.callbacks=函数(cb){ //... } instance.is_allowed=函数() //…检查,返回布尔值 } window.instance=instance; })(本条); 如果有人想要操纵此代码(例如恶意用户),他会用自己的
(功能(窗口){
var options={/*一切都在哪里*/};
变量实例=(函数(选项){
对于(选项中的var i){
if(选项.自有财产(i)){
此[i]=选项[i];
}
}
})(可选方案);
instance.callbacks=函数(cb){
//...
}
instance.is_allowed=函数()
//…检查,返回布尔值
}
window.instance=instance;
})(本条);
如果有人想要操纵此代码(例如恶意用户),他会用自己的函数重写is_allowed
函数,例如,使用地址栏(他没有firebug,谁知道呢)
这是一个简单的例子,但关键是,Javascript中的任何内容都可以被覆盖
我知道在es5中我们有Object.defineProperty,因此您可以设置:
//是显式的
Object.defineProperty(实例“是否允许”{
可枚举:false,
可配置:false,
可写:false,
值:函数(){
//检查
}
});
实际上,从这个意义上讲,最好使用Object.freeze(instance)
或Object.seal(instance)
而不是Object.defineProperty
,因为后者可以用writeable:false
再次调用(傻吧?)
有没有什么方法可以让它在旧浏览器(即IE6-8)中工作而不太麻烦?如果这是不可能的,那么我就耸耸肩继续前进。如果
被允许
完全是本地的呢
(function(window){
var options = {}, is_allowed;
var instance = (function(options){
for (var i in options) {
if (options.hasOwnProperty(i)) {
this[i] = options[i];
}
}
return this;
})(options);
instance.callbacks = function(cb){
/* ... */
};
function check_allowed(){
/* check and let this function set [is_allowed] */
};
window.instance = check_allowed()
? instance
: { callbacks: function(){(alert('not allowed'));} };
} (this) );
模型
顺便说一句:在您的代码中,窗口。实例
将是未定义的
我不会说我是这方面的专家。但假设您可以完全包装代码并使用事件触发行为,则可以使用如下结构:
Closed = function(args) { return (function() {
"use strict";
var secret, init, get_secret, use_secret;
init = function(something){
secret = something;
};
get_secret = function() {
return secret;
};
use_secret = function () {
console.log(secret);
};
/* Run constructor */
init(args);
/* Publish API */
return { use_secret:use_secret };
}())};
用obj=Closed(“任何东西”)设置它
您仍然可以让恶意用户覆盖use\u secret()
方法,因为它是公开的,但是get\u secret()
方法和任何其他内部结构都受到保护
如果您的init方法向应用程序声明了许多事件绑定,那么可以通过这种方式将状态保持为私有状态。这些事件将能够触发内部方法,因为它们是从内部闭包绑定的,但外部代码不会看到它们
保留地
虽然这可能会解决你的问题,但我不是100%确定它会解决,无论如何,这是不值得信任的。只要安全性在客户端,任何想要渗透您的应用程序的用户都可以。没有什么可以阻止他们在事后制作自己的对象来替换你的对象,不管是ES5还是非ES5
对于任何真正需要安全的东西,您必须在服务器端重新验证。永远不要信任客户端代码来保护您,请求甚至可能不是来自您所服务的页面
如果有人想要操纵此代码(恶意用户
例如),他会用自己的函数重写is_allowed函数
他可以重写您的整个javascript代码,甚至不使用浏览器,而是模拟“无浏览器”的服务器请求
有没有办法在旧浏览器(即IE6-8)中工作而不需要
太麻烦了
不可以。您全局公开的任何内容都可以由用户更改,这取决于浏览器限制javascript:
行为,以避免用户被愚弄访问预先制作的链接。Firefox最近对javascript URL协议做了一些更改
如本文所述:
从Chrome v13、Firefox v6和IE 9开始,浏览器开发人员已经注意到“javascript:”协议的危险,并随后禁止使用代码。。。在Chrome和IE中,“javascript:”子字符串在粘贴代码时被剥离,而Firefox不再在活动页面的范围内执行脚本
所以
如果这是不可能的,那我就耸耸肩继续前进
您应该。如果您的应用程序依赖于在客户端机器上运行的JavaScript代码的完整性,那么这就是您的实际问题。你不应该关心那里发生了什么,只需要确保你只发送了客户端可以看到的内容,并验证和清理了所有输入的内容。那么可以操作的AJAX呢(想想验证以外的其他场景)。实际上,它不是我的应用程序,它是一个运行在其他人项目上的库。也许你可以考虑使用一些垫片来改进代码,以支持跨浏览器ES5对象功能。请看另一个可用的:。@Niko是正确的。不要担心“恶意”程序员会覆盖它。如果他想要恶意,没有什么能阻止他向服务器发送不正确的请求,不管你使用什么Javascript。这大概就是我目前正在做的。。。我只是想避免我目前拥有的一切,任何对我所编写的jquery插件的篡改,因为我不知道人们将如何使用它,所以我想保持它的“防篡改”,所以至少我的工作完成了
Closed = function(args) { return (function() {
"use strict";
var secret, init, get_secret, use_secret;
init = function(something){
secret = something;
};
get_secret = function() {
return secret;
};
use_secret = function () {
console.log(secret);
};
/* Run constructor */
init(args);
/* Publish API */
return { use_secret:use_secret };
}())};