问题
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 that two tabs? How can i do this?
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<ul>
<li><a href="http://localhost:8080/struts_tab/abcForm1.action" oncontextmenu="return false;"><span>First Click[Right Click disabled]</span></a></li>
<li><a href="http://localhost:8080/struts_tab/defForm2.action"><span>Second clieck[Not more than 2 tabs]</span></a></li>
</ul>
</body>
</html>
回答1:
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. $('<input>').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<String, String[]> request = ((HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST)).getParameterMap(); if (request.containsKey("tabId")){ String tabId = (String) request.get("tabId")[0]; List<String> 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.
来源:https://stackoverflow.com/questions/30726627/restriction-on-number-of-opened-tabs