Joh*_*ria 11 prototype lotus-notes lotus-domino xpages xpages-ssjs
如果有人在nsf中使用javascript原型,如何清理Domino服务器中的SSJS(服务器端Javascript)?
马克·罗登发现了XPage SSJS的一个巨大弱点 :(感谢David Leedy告诉我这件事并向我展示这篇文章).
如果您有以下SSJS代码:
var dummyObj = {}
dummyObj.prototype.NAME = "Johann"
Run Code Online (Sandbox Code Playgroud)
XPages SSJS并不关心你使用var(var表示变量必须是本地的),它使dummyObj.NAME在整个服务器中可见,其值为Johann.因此,如果同一服务器中的另一个nsf使用具有相同名称的var,则它将继承整个原型:
var dummyObj = {}
println(dummyObj.NAME) /*prints "Johann" */
Run Code Online (Sandbox Code Playgroud)
这是一个巨大的错误(一个使得不可靠的XPage SSJS IMO).即使你根本不使用原型,如果他的应用程序中的其他人做了类似这样的事情:
String.prototype.split = function(){ return "I broke this method" }
Run Code Online (Sandbox Code Playgroud)
它将破坏使用无辜split()的同一服务器中的所有应用程序.
所以,问题是:如果有人"错误地"在NSF中写下以下SSJS(XPages服务器端Javascript):
String.prototype.split = function(){ return "I broke this method" }
Run Code Online (Sandbox Code Playgroud)
如何将String.prototype.split()修复为原始值?
正如Mark Roden所说,重启HTTP任务并不能解决问题.
////////////////////////////////////////////////// /////////
编辑1:为什么我认为这是一个巨大的错误:
我是Javascript粉丝但IMHO @MarkyRoden在SSJS中发现了一个巨大的错误.垫片和填充物实际上不是主要问题.Eval被认为是一种不好的做法,但原型对象是基本Javascript的基本元素.这是向Javascript类添加方法的标准和首选方法,它还需要继承和各种OOP内容.因此,您需要在服务器级别使用某种命名空间以避免冲突.所有这些都非常糟糕,但最大的问题是,一个应用程序中的一行代码可能会破坏服务器中的所有应用程序.是的,您可以信任您的开发人员,但其中一人可能会错误地编写错误的行,并且Domino服务器也可以拥有来自不同软件供应商的数百个应用程序.在代码审查中设置责任不是一个可靠的程序.也许是时候在SSJS中拥有一个真正的javascript引擎,比如V8,Spidermonkey,Chakra或Rhino.作为一种解决方法,我正在思考Tommy Valand 在SSJS中与Rhino的想法.
编辑2:情况更糟.你可以这样做:
prototype.importPackage = null
Run Code Online (Sandbox Code Playgroud)
要么
prototype.Array = null
Run Code Online (Sandbox Code Playgroud)
正如你在@SvenHasselbach的文章中看到的那样:http://hasselba.ch/blog/?p = 1371
编辑3:IBM:你告诉我我可以使用SSJS.来吧!请修复它,它是AWFUL.请让我们正式向IBM报告此问题.
您可以使用以下Java代码重置SSJS解释器:
FacesContextExImpl fc = (FacesContextExImpl) FacesContextExImpl.getCurrentInstance();
UIViewRootEx2 uiRoot = (UIViewRootEx2) fc.getViewRoot();
JSContext jsContext = uiRoot.getJSInterpreter().getJSContext();
jsContext.getRegistry().init(jsContext);
Run Code Online (Sandbox Code Playgroud)
这将重新初始化注册表和所有原型函数.
编辑:将fc的声明更改为正确的类型.
编辑2: 这是SSJS版本:
var uiRoot = facesContext.getViewRoot();
var jsContext = uiRoot.getJSInterpreter().getJSContext();
var reg = jsContext.getRegistry();
reg.init( jsContext );
Run Code Online (Sandbox Code Playgroud)
我是否正确理解您是否要清理SSJS解释器以避免与您自己的原型扩展冲突?只是为了澄清上面的答案:这一次重新初始化了SSJS解释器.而且只有一次.您必须反复执行此操作,因为在重新初始化之后,服务器上的另一个应用程序可以再次覆盖原型功能.这就是为什么这不是一个真正的解决方案,它是你最初问题的答案.
如果您的代码尝试使用您的扩展程序时其他应用程序将执行相同操作,则会产生令人反感的后果...