- 浏览: 112271 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
墨子宇:
so,为了使用JSLint我还得装一个aptana?
eclipse 添加 JSLint 插件 -
lvjun106:
楼主可以看下这篇文章,介绍的很详细。http://www.os ...
eclipse 添加 JSLint 插件 -
newsletterBroker:
呵呵,感觉不错!
Jquery 源码中的 正则表达式 分析 -
jayliud:
String.prototype.count = funct ...
百度web前端笔试
作者 周爱民 发布于 2010年6月2日 上午12时5分
从语言学的角度上来说,允许代码无节制地使用全局变量,是最错误的选择之一。而更可怕的,就是一个变量"可能"成为全局的(在未知的时间与地点)。但是这 两项,却伴随JavaScript这门语言成功地走到了现在。
也许是限于浏览器应用的规模,所以这一切还迟迟没有酿成灾难。在此之前,出现了两种解决方案。一种是ECMA在新的规范(Edition 5)中对此做出了限制,其中最重要的一条便是eval()的使用变得不再随意和无度。而另一种方案,则是相对没有那么官僚与学术的,尽管也拥有一个同样学 术的名字:沙箱。
沙箱(Sandbox)并不是一个新东西,即使对于JavaScript来说,也已经存在了相当长的时间。在SpiderMonkey JS的源代码中,就明确地将一个闭包描述为一个沙箱。这包含着许多潜在的信息:它有一个初始环境,可以被重置,可以被复制,以及最重要的,在它内部的所有操作,不会影响到外部.
当然事实上远非如此。JavaScript里的闭包只是一个"貌似沙箱"的东西--仍然是出于JavaScript早期的语言规范的问题,闭包不得不允许 那些"合法泄漏"给外部的东西。而对于这一切无法忍受的前端工程师们,开始寻求另外的解决之道,这其中相对较早的尝试,是基于IFRAME的实践。例如 dean.edwards在2006年提出过的方案(注1):
a_frames.document.write(
|
"<script>"
+
|
"var MSIE/*@cc_on =1@*/;"
+
// sniff
|
"parent.sandbox=MSIE?this:{eval:function(s){return eval(s)}}"
+
|
"<\/script>"
|
);
|
显然,由于在不同的IFRAME中运行着各自的JavaScript引擎实例,所以上述的方案也意味着沙箱是"引擎"这个级别的:在任何一个沙箱中 的崩溃,将导致该引擎以及对应IFRAME崩溃。但--理论上说--不会影响整个浏览器。
问题是,这并不那么理想。往往的,引擎会导致整个浏览器锁在那里,例如用alert()弹出一个对话框而又因为某种意外失去了焦点。又或者单个的 IFRAME会导致全局的CPU被耗光,例如一个死循环。于是更加复杂的方案--在JavaScritp中包含一个完整的执行器--出现了。最有名的则是 Narrative JavaScript,它内建了一个执行器,用于逐行地解释执行JavaScript代码,这使得它可以控制所有的代码执行序列,或者随时重置整个执行引 擎--如同一个沙箱所要做的那样。
这一切或者太过依赖于环境,又或者太过复杂,但都不乏追随者。例如jsFiddle这个项目(注2)在"嵌入或装载"这样的路子上就已经有了不俗的 成绩。但是,YUI在新版本中却给出了它自己的选择:以更加明确的编程约定,来实现应用级别的沙箱。这包括一个非常简单的、新的YUI语法:
YUI().use(
'dom-base'
,
function
(Y) {
|
// Y是一个新的沙箱
|
});
|
在'dom-base'位置上,可以是1到N个字符串,表明一个需要在沙箱中装载的模块列表。这可以是沙箱的初始列表,或者后续的callback函数 (亦即是用户代码)所需依赖的模块列表。在这种实现方案中,YUI为每个沙箱维护各自的装载模块列表和上下文环境中的变量、成员。但是出于 JavaScript语言自己的局限,这个沙箱依然是相当脆弱的。例如下一示例中沙箱内的代码就会污染到全局:
YUI().use(
''
,
function
(Y) {
|
abc = 1234;
//<--这里可能导致一个全局变量'abc'被隐式地声明
|
});
|
同样,在上述的沙箱里也可以使用类似window、document等全局变量、修改它们的成员或无限制地调用方法(例如使用 setTimeout()来创建时钟)。所以YUI的沙箱事实上是靠"规约"来约束的,而不是真正意义上的沙箱。当然,这也意味着,如果用户能按照规约来 处理沙箱内的代码,那么也就能自由地享用它带来的便利:安全、移植和有效的隔离副作用。
而我们再穷究其根底,YUI沙箱的实质不过是一行:
// code from yui.js
|
// - mod.fn(this, name)
|
mod.entryFunc(sandbox, modName);
|
其实际含义是:
- mod :沙箱当前装载的模块;
- entryFunc : 上述模块的入口函数;
- sandbox :当前的沙箱的实例,即YUI()返回值;
- modName:模块名
除了依赖关系(以及可能需要的异步加载)之外,YUI沙箱环境仅是用下面的代码来简单地调用callback函数:
callback(Y, response);
|
然而这些需求的实现并不那么复杂。首先,我们设定数据结构mod为一个对象:
{ name:modName, fn: entryFunc, req: [], use: [] }
|
则一个环境对象env,将包括多个mod(将它们处理成对象而非数组,主要是便于使用名字来索引模块)和以及对它们进行管理操作的方法:
{ mods:{}, used:{}, add:..., use:...}
|
最后,所谓一个沙箱sandbox,就是上述环境对象的一个实例,并在初始时sandbox.mods与sandbox.used为空。由此简单的实现为:
/**
|
* tiny sandbox framework
|
* mirror from YUI3 by aimingoo.
|
**/
|
function
Sandbox() {
|
if
(!(
this
instanceof
arguments.callee))
return
new
arguments.callee();
|
this
.mods =
this
.mods || {};
|
this
.used = {};
|
}
|
Sandbox.prototype = {
|
add:
function
(modName, entryFunc, reqArr, useArr) {
|
this
.mods[modName] = { fn: entryFunc, req: reqArr, use: useArr }
|
},
|
use:
function
() {
|
var
mods = [].slice.call(arguments, 0);
// 0..length-2 is modNames
|
var
callback = mods.pop();
// length-1 is callback
|
var
recursive_load =
function
(name, mod) {
|
if
(!
this
.used[name] && (mod=
this
.mods[name])) {
|
mod.req.forEach(recursive_load,
this
);
|
mod.fn(
this
, name);
|
mod.use.forEach(recursive_load,
this
);
|
this
.used[name] =
true
;
|
}
|
}
|
mods.forEach(recursive_load,
this
);
|
callback(
this
);
|
}
|
}
|
现在我们来尝试一个与YUI类似的语法风格:
Sandbox().use(
''
,
function
(){
|
alert(
'user code.'
);
|
});
|
或者,先向整个Sandbox环境注册一些模块(在真实的框架实现中,这一步可能是通过框架的装载器来初始化):
// for test, entry of mods
|
f1 =
function
() { alert(
'f1'
) };
|
f2 =
function
() { alert(
'f2'
) };
|
f3 =
function
() { alert(
'f3'
) };
|
// mods for global/common env.
|
Sandbox.prototype.mods = {
|
'core'
: { fn: f1, req: [], use: [] },
|
'oo'
: { fn: f2, req: [
'core'
], use: [
'xml'
] },
|
'xml'
: { fn: f3, req: [], use: [] }
|
}
|
然后再尝试在一个沙箱实例中运行代码:
// f1 -> f2 -> f3 -> user code
|
Sandbox().use(
'oo'
,
function
(){
|
alert(
'user code.'
);
|
});
|
其实即便是上述代码中用于处理模块依赖的逻辑,也并不是什么"神奇的"代码或者技巧。除开这些,这样的沙箱隔离泄露的能力还抵不过一个嵌入式DSL语言。 而后者所应用的技巧很简单,看不出什么花招(注3):
with
(YUI())
this
.eval(
"... mod_context ... "
);
|
这样一来,在mod_context里的代码就只会在YUI()的一个实例中造成污染了。当然,仍然是源于JavaScript的限制,我们还是无 法避免一个变量泄露到全局--除非,我们回到js in js这个项目(注4),真的在环境中重新初始化一个js引擎。
从这一意义上来说,引擎级别的沙箱与操作系统的进程一样,带来的是终级的解决方案,所以Chrome、IE等等主流浏览器纷纷有了"独立进程"模 式。而在这样的背景之下,试图用"框架内置沙箱"来改善ECMAScript ed3中一些设计疏失的种种努力,不过是一张张空头的支票罢了。
甚至,用这本支票签完单也未必有人会收的。
备注
注1:http://dean.edwards.name/weblog/2006/11/sandbox/
注2:http://jsfiddle.net/
注3:http://blog.csdn.net/aimingoo/archive/2009/09/08/4532496.aspx
注4:http://mxr.mozilla.org/mozilla/source/js/narcissus/
原文地址:http://www.cnblogs.com/bluedream2009/archive/2010/06/05/1752180.html
发表评论
-
execCommand
2011-11-25 16:12 1117mozilla 文档地址:https://develop ... -
javascript DOM
2011-11-21 10:50 1030原文地址: http://blog.mo ... -
支持ctrl,shift键的拖拽排序
2011-08-26 11:23 1168终于搞定了,太不容易了。最近公司要弄一个拖拽排序的 ... -
javascript 封装 继承
2011-08-16 17:37 1121原文地址:http://www.ruanyifeng.com/ ... -
javascript 中的闭包
2011-08-16 16:37 921文章地址:http://www.ruanyifeng.com/ ... -
javascript 排序
2011-08-31 19:41 912//生成20-100之间的20个随 ... -
seajs 源码 学习 1
2011-08-10 17:32 0global.seajs = { _seajs: this ... -
seajs 源代码 学习
2011-08-11 14:08 3196这段时间学习了一下seajs,也用了seajs写了不少的d ... -
null 和 undefined
2011-07-31 15:05 878原文地址:http://blog.csdn.net/aimin ... -
辩:javascript 的数据类型
2011-07-29 11:18 1173关于“javascript 的数据 ... -
跨域请求
2011-07-12 11:34 0原文地址:http://itgeeker. ... -
uglifyJS
2011-04-26 12:21 0-b or --beautify — o ... -
JavaScript DO 框架 学习
2011-04-22 14:56 1816昨天在github找东西的时候,发现上了克军的DO框架,感觉不 ... -
prettfy demo
2011-02-23 08:29 1238<!DOCTYPE html PUBLIC " ... -
JavaScript 测试题
2011-02-16 12:07 1067console.log(" ... -
javascript 中的apply和call方法
2010-12-31 15:11 777一直以来不明白,今天算是搞明白了apply和call方法了。记 ... -
jquery 插件 开发 模板
2010-12-10 13:09 948原文来自网上。 (function($) { ... -
31个最实用的Javascript工具
2010-12-08 14:56 1066原文地址:http://developer.51cto.com ... -
27个必备的Javascript开发工具
2010-12-01 14:59 1065原文地址:http://blog.mcncc.com/4275 ... -
选择器 效率 图
2010-11-22 11:27 718以后用jquery的选择器这回有依据了
相关推荐
华为沙箱技术
深度威胁分析沙箱技术介绍.pdf
沙箱技术是一种重要的网络安全防御手段,它通过创建一个隔离的环境来执行可能包含恶意代码的文件或应用程序,以便在不损害真实系统的情况下检测潜在的威胁。沙箱的基本原理是利用虚拟化技术,使得受控的代码在一个...
"Firehunter APT沙箱安全技术方案" .Firehunter APT沙箱安全技术解决方案是华为提供的一种APT沙箱安全解决方案,旨在检测和防御APT攻击。该解决方案基于行为特征检测和机器学习技术,能够检测未知恶意文件和未知...
FireHunter6000沙箱技术白皮书.pdf
为解决这些问题,云原生沙箱环境技术应运而生,下面将详细介绍此技术的核心知识点。 首先,云原生沙箱环境技术的出现,是为了降低云原生技术的使用门槛,提供一个简单、免费的环境,让开发者可以轻松地进行学习、...
沙箱逃逸技术总结。
深度威胁分析沙箱技术介绍 深度威胁分析沙箱技术是一种高级威胁防护解决方案,旨在检测和防护高级未知恶意程序、APT 攻击和零日攻击。该技术基于沙箱分析模块,可以自动执行针对可疑文件及 URL 的分析检测,生成...
华为的FireHunter APT沙箱安全技术方案是针对高级持续性威胁(Advanced Persistent Threat, APT)的一种解决方案,旨在提供对未知威胁的有效检测和防御。APT攻击通常由具有政府背景的组织发起,针对政府、央企国企、...
FireHunter6000沙箱技术白皮书.docx
在IT行业中,安全沙箱是一种重要的安全机制,尤其在Flash技术中扮演着核心角色。Flash安全沙箱的主要目的是为了限制并隔离运行的Flash内容,防止它们对用户系统造成潜在的危害。下面将详细介绍Flash安全沙箱的基本...
b) **受信任的本地沙箱**:当SWF文件位于特定的信任目录(例如,FlashPlayerTrust目录)中时,它们会获得更高的权限,能够与任何其他SWF文件交互,并且可以从本地或远程位置加载数据。这提供了一种方式来运行需要更...
本项目“SpringBoot+Vue支付宝沙箱支付”旨在教你如何在SpringBoot后端与Vue前端环境中实现支付宝的沙箱测试环境支付功能,从而在不涉及真实交易的情况下测试支付流程的完整性和安全性。 首先,我们需要了解什么是...
沙箱技术是信息安全领域的重要概念,它创建了一个虚拟环境,被称为“沙箱”,在这个环境中,程序的运行不会影响到真实系统的状态。即使在沙箱内的程序执行了有害操作,也不会对用户的实际操作系统造成任何损害。这种...
Chrome和IE9浏览器都采用了沙箱技术来增强其安全性,尤其是对于网页浏览时的插件和JavaScript执行。这种技术的核心思想是将敏感操作限制在一个受控的环境中,即使发生恶意行为,也不会影响到操作系统或用户数据的...
在 Flash 技术中,安全沙箱的概念尤为关键,因为它允许 Flash 内容在网页上运行,同时限制了其对用户计算机的访问权限。当我们面临“Java, C#, Delphi 解决 Flash 安全沙箱问题”的场景时,这意味着我们需要在这些...
360沙箱,全称为360 Security Sandbox,是360安全卫士的一个重要组件,它通过虚拟化技术创建一个独立的操作系统环境,让用户可以在这个环境中运行可能含有风险的程序或浏览网页,而不会对实际操作系统造成影响。...
隔离沙箱技术是一种在计算机安全领域中广泛应用的技术,它的主要目的是为用户提供一个安全的环境来运行可能含有恶意软件或不信任的程序,而不会对主机系统造成任何损害。标题提到的“比360好”的隔离沙箱,暗示了这...