Restriction on number of opened tabs

后端 未结 1 1219
刺人心
刺人心 2021-01-14 17:53

There are some links on web-page.

On right click there is option of \'open link in new tab\'(browser option).

I want to restrict user for not opening more t

1条回答
  •  星月不相逢
    2021-01-14 18:34

    You can't restrict the user from opening a new tab.
    (This reminds me the old pop-ups with no buttons, no address bar, but still responding to backspace and other events)

    You can however make your app recognize the attempt of opening a third tab, and load a different result like an error message, for example:

    Maximum open tabs limit reached. Please use no more than two tabs concurrently. close this tab

    To do this, you can use HTML5 sessionStorage.
    Note: Web Storage (sessionStorage and localStorage) is supported on every browser nowadays.

    sessionStorage

    This is a global object (sessionStorage) that maintains a storage area that's available for the duration of the page session. A page session lasts for as long as the browser is open and survives over page reloads and restores. Opening a page in a new tab or window will cause a new session to be initiated.

    Then you can

    • if not present in sessionStorage, generate an unique token in JSP, and put it in sessionStorage,

      $(function(){
          // Read the ID. If it's null, this is a new tab: 
          // generate the ID and store it for later.
          var tabId = sessionStorage.getItem("tabId");
          if (tabId == null){
              tabId = Math.random();
              sessionStorage.putItem("tabId",tabId);
          }
      
    • send it back to the action

          // Add the ID to the form (as hidden field), 
          // so it will be posted back in next submission.
          $('').attr('type'  , 'hidden')
                      .attr('name'  , 'tabId')
                      .attr('value' , tabId)
          .appendTo('form');
      });
      

      , maybe to a setter in a BaseAction, extendend by the other actions, and read by prepare(), or much better in an Interceptor;

    • put it in a collection checking that it doesn't contain already two elements, otherwise return the error result, that should be mapped globally:

      public String intercept(ActionInvocation actionInvocation) throws Exception {
          Action action = (Action) actionInvocation.getAction();
          if(action instanceof LimitedTabsAware){ //interface to identify special actions
              ActionContext context = actionInvocation.getInvocationContext();
              Map request = ((HttpServletRequest) 
                                  context.get(StrutsStatics.HTTP_REQUEST)).getParameterMap();
      
              if (request.containsKey("tabId")){              
                  String tabId = (String) request.get("tabId")[0];
                  List openTabs = context.getSession().get("OPEN_TABS_KEY");
      
                  if (openTabs.contains(tabId)){
                      return actionInvocation.invoke();                   
                  } else if (openTabs.size()>=2){
                      return "tabLimitExceeded"; // global result
                  } else {
                      openTabs.add(tabId);
                      context.getSession().put("OPEN_TABS_KEY", openTabs);
                      return actionInvocation.invoke();
                  }
      
              } else {
                  throw new IllegalArgumentException("There is no tabId in this request.");
              }
          } else {
              return actionInvocation.invoke();
          }
      }
      

    Then you should find a way to recognize when a tab get closed (to free one slot), by either:

    • timizing the period of validity of the elements in your collection (if you don't use a tab for some time, the session expires, and so must do the token in the collection)
    • otherwise, putting a javascript AJAX timer in your page (eg. every 30 seconds), that send a keep-alive signal to an action to refresh the validity of the element. If the tab get closed, the signal is not sent anymore.

    0 讨论(0)
提交回复
热议问题