为什么注销后点击页面上的返回按钮会显示上一页内容?

2022-01-16 00:00:00 session jquery java struts2 cache-control

我正在处理一个 Struts 2 项目.当用户单击 logout 按钮时,logout 操作会使用 session.clear() 清除会话.

I am working on a Struts 2 project. When user clicks a logout button the logout action clears the session using session.clear().

但是当用户在登出后点击浏览器中的返回按钮时,仍然显示上一页内容.

But when user clicks the back button in the browser after logout, it still displays the previous page content.

如果退出后在浏览器中单击了 back 按钮,我想将用户重定向到登录页面.

I want to redirect an user to the login page, if the back button was clicked in the browser after logout.

在我的注销操作中我还有什么需要清除的以解决这个问题吗?

Is there anything else I should clear in my logout action to solve this problem?

推荐答案

原来您的浏览器在您按下返回按钮之前正在缓存页面.浏览器缓存机制旨在通过在页面具有相同 URL 时从本地缓存中获取页面来最小化服务器访问时间.当成千上万的客户端浏览服务器时,它显着减少了服务器负载,并且似乎非常有帮助.但在某些情况下,尤其是在您的情况下,内容应该更新.后退按钮的设计目的是缓存用户正在浏览的每个页面,并在按下后退按钮时从本地缓存中检索它们.因此,解决方案是告诉浏览器在返回带有控制浏览器缓存的特殊标头的响应时不允许缓存.在 servlet 环境中,您可以使用过滤器来关闭缓存,但在 Struts2 中,您可以使用自定义拦截器.例如

Turns out that your browser is caching pages before you press the back button. The browser caching mechanism is designed so to minimize the server access time by getting the page from the local cache if the page have the same URL. It significantly reduces the server load when browsing the server by thousands of clients and seems to be very helpful. But in some cases, especially in yours the content should be updated. The back button is designed so it caches every page that a user is browsing and retrieve them from the local cache when pressed the back button. So, the solution is to tell the browser to not allow caching when returning a response with a special headers that control the browser caching. In the servlet environment you might use a filter to turn off caching but in Struts2 you could use a custom interceptor. For example

public class CacheInterceptor implements Interceptor {

private static final long serialVersionUID = 1L;

@Override
public void destroy() {}

@Override
public void init() {}

@Override
public String intercept(ActionInvocation invoication) throws Exception {
    HttpServletRessponse response = ServletActionContext.getResponse();
    response.setHeader("Cache-Control", "no-cache");
    response.setHeader("Pragma", "no-cache");
    response.setHeader("Expires", "-1");
    return invoication.invoke();
}

}

现在您可以配置此拦截器以供每个操作使用

Now you could configure this interceptor to use by every action

<package name="default" extends="struts-default" abstract="true">

    <interceptors>
      <interceptor name="cache" class="org.yourcompany.struts.interceptor.CacheInterceptor "/>
      <interceptor-stack name="cacheStack">
        <interceptor-ref name="cache"/>
        <interceptor-ref name="defaultStack"/>
      </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="cacheStack"/>

</package>

当您的包扩展 default 包时,它们会继承拦截器和拦截器堆栈,您也可以通过操作配置覆盖此配置.

When your packages extend default package they inherit the interceptor and the interceptor stack, you can also override this configuration by the action configuration.

相关文章