Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否有任何方法可以防止重写单例实例中的函数/变量?_Javascript_Singleton_Javascript Objects_Overwrite - Fatal编程技术网

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 };

}())};