一尘不染

限制打开的标签页数

jsp

网页上有一些链接。

右键单击有“在新选项卡中打开链接”选项(浏览器选项)。

我想限制用户不要打开两个以上的标签吗?我怎样才能做到这一点?

<%@ 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>

阅读 266

收藏
2020-06-08

共1个答案

一尘不染

您不能限制用户 打开 新标签页。
(这使我想起了没有按钮,没有地址栏,但仍对退格键和其他事件做出响应的旧弹出窗口)

但是,您可以使您的应用 识别打开第三个标签的尝试 ,并加载不同的结果,例如错误消息,例如:

已达到最大打开标签数限制。请同时使用两个以上的标签。close this tab

为此,您可以使用HTML5 sessionStorage
注意:如今,每个浏览器都支持 Web存储
sessionStoragelocalStorage)。

sessionStorage

这是一个全局对象(sessionStorage),用于 维护在页面会话期间可用的存储区域
。页面会话的持续时间只要浏览器处于打开状态,并且在页面重新加载和还原后仍然存在。 在新选项卡或窗口中打开页面将导致启动新会话

那么你也能

  • 如果sessionStorage中不存在,请在JSP中生成一个唯一的令牌,然后将其放入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);
    }
    
  • 发回动作

        // 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');
    

    });

,可能是BaseAction中的设置器,是其他操作的扩展,并被 Interceptor 读取prepare(),甚至 更好

  • 将其放入集合中,检查它是否已不包含两个元素,否则返回错误结果,该结果应全局映射:
    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();
    }
    

    }

然后,您应该找到一种方法来识别选项卡何时关闭(以释放一个插槽),方法是:

  • 集合中元素的有效期(如果一段时间不使用标签,会话将过期,因此必须在集合中使用令牌)
  • 否则,在页面中放置一个javascript AJAX计时器(例如,每30秒),该计时器会 keep-alive 向操作发送信号以刷新元素的有效性。如果选项卡关闭,则不再发送信号。
2020-06-08