Xpages xPage超时和新登录

Xpages xPage超时和新登录,xpages,Xpages,超时发生后,当我在xPage组件上单击somwhere时,我遇到以下问题: 它在某些框架中显示登录页面(而不是单独的完整登录页面),例如,如果我单击视图或数据表中的某个位置,它仍然显示xPage,但登录窗口显示在数据表框架中 似乎所有CSS格式在重复登录后都会失败 如何解决每个问题?假设它应该以某种方式重新加载超时/登录后未发生的页面 谢谢使用扩展库中的Keep-Alive组件。或者使用这个xSnippet 如果希望发生超时,请在onload事件中使用此代码 setInterval(funct

超时发生后,当我在xPage组件上单击somwhere时,我遇到以下问题:

  • 它在某些框架中显示登录页面(而不是单独的完整登录页面),例如,如果我单击视图或数据表中的某个位置,它仍然显示xPage,但登录窗口显示在数据表框架中

  • 似乎所有CSS格式在重复登录后都会失败

  • 如何解决每个问题?假设它应该以某种方式重新加载超时/登录后未发生的页面


    谢谢使用扩展库中的Keep-Alive组件。或者使用这个xSnippet

    如果希望发生超时,请在onload事件中使用此代码

    setInterval(function(){
    XSP.partialRefreshGet("#{id:hiddenxpdiv}", {
       onError: function() {
    window.location.href=window.location.href;
    }}
    }, 300000);
    

    您可以使用以下问题答案中的小片段劫持XPage上的所有部分刷新:

    在“劫持”函数中,您可以检查服务器返回的特定头,以确定您是否仍在登录。如果没有,您可以重定向或重新加载整个页面

    要添加标头,可以在XPage的beforeRenderResponse事件中对其进行编码,或者使用阶段侦听器。阶段侦听器可能如下所示:

    package ch.hasselba.xpages.util;
    
    import javax.faces.context.ExternalContext;
    import javax.faces.context.FacesContext;
    import javax.faces.event.PhaseEvent;
    import javax.faces.event.PhaseId;
    import javax.faces.event.PhaseListener;
    import javax.servlet.http.HttpServletResponse;
    
    public class IAmAlivePhaseListener implements PhaseListener {
    
        private static final long serialVersionUID = 1L;
    
        public void beforePhase(PhaseEvent event) {
            FacesContext fc = FacesContext.getCurrentInstance();
            ExternalContext ec = fc.getExternalContext();
            HttpServletResponse response = (HttpServletResponse) ec.getResponse();
            response.addHeader("X-I_AM_ALIVE", "1");
        }
    
        public PhaseId getPhaseId() {
            return PhaseId.RENDER_RESPONSE;
        }
    
        public void afterPhase(PhaseEvent event) {}
    
    }
    
    if( !dojo._xhr )
      dojo._xhr = dojo.xhr; 
    
    var loadOld;
    
    function hijacked( response, ioArgs ){
      var isAlive = ioArgs.xhr &&
      ioArgs.xhr.getResponseHeader("X-I_AM_ALIVE");
    
      if( !isAlive ){
          window.location.href = window.location.href;
          return false;
      }
    
      loadOld( response, ioArgs ); // call the original function 
    }
    
    dojo.xhr = function( mode, args, bool ){
      loadOld = args["load"];
      args["load"] = hijacked;
      dojo._xhr( mode, args, bool );
    }
    
    要激活阶段侦听器,必须将其添加到faces-config.xml:

    一旦标头不可用,就会停止部分刷新/事件执行,并重新加载整个站点。当登录表单出现时,不会添加HTTP头

    编辑:

    在执行部分刷新时,客户机向服务器发送一个请求,并期望响应中的HTML覆盖/替换DOM树中的现有元素。被替换的DOM元素由刷新id定义

    发送给服务器的请求是一个xhr请求,它在替换DOM之前首先检查返回代码。如果发生错误(例如HTTP返回代码404),则调用部分刷新的onError方法,否则(HTTP返回代码200)调用onComplete

    超时和XPages的问题是登录屏幕的HTTP响应代码始终为200(OK)。当会话超时并且客户端向服务器发出xhr请求时,他从服务器收到“良好响应”,并用返回的HTML代码替换现有DOM。但在本例中,它是来自登录屏幕的HTML。 用它替换刷新的DOM元素后,现有DOM的标记被破坏,最终XPage不再工作(因为JavaScript错误)

    虽然您不能将HTTP头添加到登录屏幕或更改响应代码,但我的想法是相反的:我的解决方案不是将头添加到登录屏幕并标识“坏响应”,而是添加头来标识“好”响应


    在我看来,这是一个最简单的解决方案,可以在不改变现有代码的情况下在任何应用程序上运行(只需添加几行代码并将CSJ添加到主题中)。

    但我确实希望超时发生部分刷新,如果出现错误,则进行完全刷新。然后登录页面应该显示在全屏上,我应该在哪里进行部分刷新?如果我单击表单上的任意位置(按钮、字段、视图、视图列排序等),则会出现问题。在表单的某个位置添加一个xp:div名称hiddenxpdiv添加样式可见性:hidden在其中添加一个计算文本,并将@Now()作为值,是否有合适的解决方案?我发现在启用OneUI主题和扩展库应用程序布局的页面上会出现呈现问题used@VladP:更新了我的答案。
    if( !dojo._xhr )
      dojo._xhr = dojo.xhr; 
    
    var loadOld;
    
    function hijacked( response, ioArgs ){
      var isAlive = ioArgs.xhr &&
      ioArgs.xhr.getResponseHeader("X-I_AM_ALIVE");
    
      if( !isAlive ){
          window.location.href = window.location.href;
          return false;
      }
    
      loadOld( response, ioArgs ); // call the original function 
    }
    
    dojo.xhr = function( mode, args, bool ){
      loadOld = args["load"];
      args["load"] = hijacked;
      dojo._xhr( mode, args, bool );
    }