禁用Chrome控制台中的JavaScript编辑?

4
所以,我今天才发现你可以在chrome控制台中运行javascript。我不知道你可以这样做。这实际上非常酷。
在我的rails应用程序中,我有一个外部javascript页面。我希望该页面上的某些变量是全局的,以便JS文件中的所有函数都可以访问它们。例如,我有一个地图,我希望地图对象在javascript文件中是全局的,因为这样所有的函数都可以访问同一个地图变量,而不是创建自己的变量,并且我可以将复杂的操作分解成更小的函数。
我知道如何做到这一点,并且它完美地工作。我的问题是,我能保护这些变量不受外部干扰吗?例如,您可以从chrome控制台更改所有javascript类变量的值..还可以访问和执行例如地图的方法..我已经锁定了地图设置,使其在其中一个页面上不可缩放或移动,但是从控制台中我只需输入“map.setZoom(11)”,地图就会缩放到11..我可以输入“map.dragable = true”,然后就可以拖动地图..我真的不喜欢这个..
虽然用户启用地图拖动和缩放并不是世界上最糟糕的事情..但是我仍然想禁用它。有什么想法吗?
编辑
感谢所有答案和评论。我想我只能不将任何可能被恶意利用的内容放入我的javascript中,并像将我的地图变量传递到必要的函数中以减缓人们的速度。

4
你可以将所有内容放在一个新的函数作用域中。 - Shmiddty
1
话虽如此,但真的没有使用全局变量的理由。最好是根据需要修改你的方法以将地图作为参数传递进去。 - Shmiddty
这个编码规范看起来更好吗? - user1759942
6个回答

6

您可以使用立即调用的函数表达式(IIFE)来防止变量和函数暴露在全局范围内:

var a = 10;

(function() {
    var b = 20;
})();
window.a 可以让你查看和修改 a,但是你无法使用它来修改 benter image description here 在这里试一试 我相信有一种方法可以使用检查器来编辑 b,但我还没有花时间去弄清楚。不要浪费时间试图防止用户修改他们可以查看的代码。

你的修改点非常好。此外,不要允许/期望JavaScript中包含敏感数据。 - Joseph Yaduvanshi
链接无效。 - theknightD2

5

你做不到。即使将它们包装成匿名函数,用户也可以通过调试器找到它们。作为最后的手段,他可以拦截你的流量并用其他东西替换你的JavaScript。

底线:浏览器中的JavaScript是客户端代码。客户端可以随心所欲地使用它。


3

试着像这样做:

(function(){
   //All of your current code
})();

需要注意的一点是 - Chrome开发者工具也允许您编辑javascript(不是服务器上的javascript文件,而是当前正在运行的副本)。转到Chrome Dev Tools->Sources,您可以编辑javascript文件。


2
你做不到。你说你需要在全局定义你的地图,这意味着它对所有人都是可访问的。 你可以在一个不同的作用域中定义你的地图,然后只定义“公共”的内容:
(function() {
    var map = new Map();
    window.myMap = {
        goTo: function(lat, lng) {
            map.goTo(lat, lng);
        }
    };
})();

1
根据您的架构,有几种方法可以实现此目标。使用此方法创建可重用组件,具有公共和私有属性:
var protectedScope = function () {
    var protected_var = 'protected';
    this.showProtected = function () {
        return protected_var;
    }
    this.public = 'public';               
};
var myObject = new protectedScope();

console.log('Public var: '+myObject.public); // outputs "public"
console.log('Protected via accessor: '+myObject.showProtected ()); // outputs "private"
console.log('Protected var: '+myObject.protected); // outputs undefined

任何使用var关键字声明的变量或函数都将被视为私有。任何使用this.name机制的变量或函数都将是“公共”的。

请注意,这种结构并不真正是公共或私有的,这些概念并不是语言的一部分。仍然有方法可以访问这些变量,而且人们总是可以查看源代码。只要清楚:这是一个代码组织概念,而不是安全概念。Chrome已经有了这个开发者控制台一段时间了,其他主要用户代理正在努力包含类似的工具(或已经这样做)。还有像Firebug这样的工具,允许用户完全访问您的JavaScript运行时环境。这不是开发人员可以完全控制的领域。

在此尝试:http://jsfiddle.net/cf2kS/

更多阅读

JavaScript中的私有成员,作者是道格拉斯·克罗克福德* - http://www.crockford.com/javascript/private.html JS中的面向对象编程,第一部分:公共/私有变量和方法,来源于http://phrogz.net - http://phrogz.net/JS/classes/OOPinJS.html MDN上的JavaScript对象管理 - https://developer.mozilla.org/en-US/docs/XUL_School/JavaScript_Object_Management MDN上的闭包 - https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Closures

如果我编辑protectedScope原型并为私有变量添加自定义getter、setter,会发生什么? - Keo Strife
伪私有变量的问题在于,你必须将任何getter或setter建立在代码的主体中--不能使用原型来访问伪私有变量。这个概念之所以起作用,是因为你正在函数体内形成闭包。当你通过其原型添加或修改函数时,该代码不会关闭内部作用域,因此它无法访问该作用域中的变量。如果你在函数体内使用this.myVal = 1;,则原型函数可以访问它,但也会被公开暴露。 - Chris Baker

0
Object.defineProperty(map, 'zoom', {value:1});

或者

Object.defineProperty(map, 'zoom',{
    set: function(){console.warn('Access denied!');},
    get: function(){return 1;}
    }); 

演示

或者

Object.defineProperty(Object.prototype, 'protect', {
    value:  function(ignore){
        var childObjects = [], ignore = ignore || [];
        ignore.push(this);      
        if(this instanceof MimeType)return; //Chrome Fix //window.clientInformation.mimeTypes[0].enabledPlugin[0] !== window.clientInformation.mimeTypes[0]
        for(var prop in this){
            if(typeof this[prop] === "unknown")continue; //IE fix
            if(this[prop] instanceof Object){
                var skip = false;
                for(var i in ignore)
                    if(ignore[i]===this[prop]){
                        skip = true;
                        break;
                    }
                if(!skip)childObjects.push(prop);   
            }       
            var d = Object.getOwnPropertyDescriptor(this, prop);
            if(!d || !d.configurable || !d.writable)continue;
            var that = this;
            (function(){
                var temp = that[prop];
                delete that[prop];
                Object.defineProperty(that, prop,{
                    set: function(){console.warn('Access denied!');},
                    get: function(){return temp;}
                });
            })();
        }
        for(var i = 0;i<childObjects.length;i++)
            this[childObjects[i]].protect(ignore);
    }  
});
this.onload=function(){this.protect();} //example

演示


嗯...那么这将防止用户更改缩放属性,但我是否需要为每个全局对象的每个属性都有类似的语句呢?这在防止用户更改地图缩放方面对我有所帮助,这实际上非常好,因为如果更改地图缩放是可怕的,这将阻止它们,但仍然留下了控制台和其他所有东西。 - user1759942
@user1759942 看第三个方法,那个能跨浏览器保护 所有 东西,不仅可以防止来自控制台的攻击,还可以防止来自地址栏的 javascript:xy 攻击。 - user669677

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接