我有问题。我定义了一些全局变量,并将其命名为一个名为“app”的对象。 例如:
window.app : {
foo : null,
bar : null,
}
好吧,我想通过调用app.foo =“baz”或app.bar =“baz”来修改任何模块中的变量,但我不希望用户能够从浏览器控制台(元素检查器)修改这些变量。
有可能吗?
PD:嗯,我有一个与服务器同步的Backbone.js集合。我不希望用户能够使用控制台修改该集合答案 0 :(得分:6)
没有。浏览器是用户的域。他们可以通过各种方式修改脚本并注入自己的功能(通过控制台或浏览器插件)。这就是为什么你不应该盲目信任服务器端用户输入的原因之一。
他们甚至可以手动伪造一个完整的请求,诱使您的服务器认为您的javascript代码提出了一些请求。
如果您希望这些值安全,则需要将它们保留在服务器上。当然,只要您有可能再次验证服务器上的值,您就可以将它们发送给客户端。
答案 1 :(得分:2)
使用户无法(轻松)修改变量的唯一方法是将它们从全局范围中删除 - 类似于
!function() {
foo = null;
bar = null;
}()
您需要重新设计模块相互交互的方式来实现这一目标。像Angular.js这样的MVC框架会有所帮助。
尽管如此,您绝不应该依赖此作为安全机制 - 浏览器完全由用户控制。
答案 2 :(得分:0)
避免从浏览器控制台(轻松)修改javascript变量的一种可能方法是使用get operator(ECMAScript 5)或getter-function。
为了能够定义“私有”变量,匿名函数定义了本地范围内的变量,因此它不是全局可用的。 (如joews的回答中所述)
如前所述,这不会使操纵变量变得不可能。
通过get运算符:
window.app = (function () {
var _foo = 123; // private variable
return {
get foo () { return _foo; }
};
}());
// --- accessing app from the console ---
// app.foo is readable from console, but not modifiable
console.log(app.foo);
app.foo = 234;
console.log(app.foo); // 123
// However, app.foo can still be modified via Object.defineProperty or
// removed with the delete operator
通过getter-function(旧浏览器,例如IE< 9):
window.app = (function () {
var _foo = 123; // private variable
return {
foo: function() { return _foo; }
};
}());
// --- accessing app from the console ---
console.log(app.foo()); // 123
// However, the foo function can still be overwritten.
// But at least, the internal _foo variable is unaffected.
app.foo = function () { return 234; }
答案 3 :(得分:0)
对于仍在寻找此问题解决方案的用户,请在分配变量而不是 var 时使用 const 修饰符。现在尝试从浏览器控制台更改变量的值。它将引发错误未捕获的TypeError:分配给常量变量,这将防止您的数据被修改。