有人在nsf中使用javascript原型(prototype)后,如何在Domino服务器中清除SSJS(服务器端Javascript)?
马克·罗登(Mark Roden)在XPages SSJS中发现了一个huge weakness :(感谢大卫·李迪(David Leedy)告诉我这件事,并向我展示了这篇文章)。
如果您具有以下SSJS代码:
var dummyObj = {}
dummyObj.prototype.NAME = "Johann"
XPages SSJS不在乎您使用 var (var表示变量必须是本地变量),它使整个服务器中都可以看到 dummyObj.NAME ,值 Johann 。因此,如果同一服务器中的另一个nsf使用具有相同名称的var,则它将继承整个原型(prototype):
var dummyObj = {}
println(dummyObj.NAME) /*prints "Johann" */
这是一个巨大的错误(使XPages SSJS IMO变得不可靠的错误)。即使您根本不使用原型(prototype),但如果他的应用程序中的其他人执行了以下操作:
String.prototype.split = function(){ return "I broke this method" }
它将破坏使用无辜 split()的同一服务器上的所有应用程序。
因此,问题是:如果有人“错误地”在NSF中编写了以下SSJS(XPages服务器端Javascript):
String.prototype.split = function(){ return "I broke this method" }
如何将String.prototype.split()固定为其原始值?
正如Mark Roden所说,重新启动HTTP任务并不能解决它。
//////////////////////////////////////////////////////////////
编辑1:为什么我认为这是一个巨大的错误:
我是Java语言爱好者,但是恕我直言@MarkyRoden发现了SSJS中的一个巨大错误。垫片和填料并不是真正的主要问题。众所周知,Eval是一种不好的做法,但是原型(prototype)对象是基本Javascript的基本元素。这是向Javascript类添加方法的标准且首选方式,继承和各种OOP stuff也是需要的。因此,您将需要在服务器级别使用某种命名空间,以避免发生冲突。所有这一切确实很糟糕,但是一个巨大的问题是,一个应用程序中只有一行代码会破坏服务器中的所有应用程序。是的,您可以信任您的开发人员,但是其中一位开发人员可能会错误地写一条糟糕的话,而且Domino服务器可以包含来自不同软件供应商的数百个应用程序。在代码审查中设置责任不是一个可靠的过程。也许是时候在SSJS中使用真正的JavaScript引擎了,例如V8,Spidermonkey,Chakra或Rhino。作为解决方法,我正在考虑类似Tommy Valand的idea with Rhino in SSJS的问题。
编辑2:甚至更糟。您可以执行以下操作:
prototype.importPackage = null
或者
prototype.Array = null
您可以在@SvenHasselbach的文章中看到:http://hasselba.ch/blog/?p=1371
编辑3:IBM:您告诉我可以使用SSJS。来一个!请修正此错误。请让我们正式向IBM报告此问题。
最佳答案
您可以使用以下Java代码重置SSJS解释器:
FacesContextExImpl fc = (FacesContextExImpl) FacesContextExImpl.getCurrentInstance();
UIViewRootEx2 uiRoot = (UIViewRootEx2) fc.getViewRoot();
JSContext jsContext = uiRoot.getJSInterpreter().getJSContext();
jsContext.getRegistry().init(jsContext);
这将重新初始化注册表和所有原型(prototype)功能。
编辑:将fc的声明更改为正确的类型。
编辑2:
这是SSJS版本:
var uiRoot = facesContext.getViewRoot();
var jsContext = uiRoot.getJSInterpreter().getJSContext();
var reg = jsContext.getRegistry();
reg.init( jsContext );
我是否正确理解您的意思,就是要清理SSJS解释器以避免与您自己的原型(prototype)扩展发生冲突?
只是为了澄清上面的答案:这将一次重新初始化SSJS解释器。而且只有一次。
您必须一遍又一遍地执行此操作,因为在重新初始化之后,服务器上的另一个应用程序可以立即再次覆盖原型(prototype)功能。这就是为什么这不是一个真正的解决方案,而是对您最初的问题的解答。
如果其他应用程序在您的代码尝试使用扩展程序时执行相同的操作,则会产生严重的后果...