防止返回按钮

10

我正在使用C#的ASP.NET MVC上的Razor。

我正在调用外部网页来处理信用卡,它会返回给我一个收据。然后我会显示收据。

我希望防止他们回到之前的屏幕。

由于这些是.cshtml文件,所以我没有像asp一样的底层cs页面来获取事件。

这个收据页面是一个View,所以我不能在头部放置JavaScript,因为它会影响使用它的每个页面。

有人知道如何在这种情况下防止返回按钮吗?


这将是一段JavaScript代码来实现此功能。C#与此无关,因为C#全部在服务器端。我相信你可以在Stackoverflow上搜索到答案。[编辑:我已经为您搜索了。](http://stackoverflow.com/search?q=prevent+back+button+browser) - Gromer
另外,如果您在 Razor 文件中使用节,您可以从特定的部分视图 Razor 文件向页面注入 JavaScript。查看此博客以获取更多信息:http://weblogs.asp.net/scottgu/archive/2010/12/30/asp-net-mvc-3-layouts-and-sections-with-razor.aspx - Gromer
浏览器不能禁用脚本,从而忽略它吗? - ErocM
是的。无论如何,您仍然需要编写代码来确保人们不会搞砸东西。或者如果JS被禁用,只需防止用户使用该网站。但这个决定取决于网站的功能、用户群等等。 - Gromer
6个回答

14

一种可能性是在客户端对不想返回的页面进行缓存排除。可以通过设置适当的响应头来实现。以下是一个示例,使用[NoCache]自定义动作过滤器装饰相应的控制器操作。


7
首先,如果之前的页面向服务器提交了数据,最好在成功处理后使用Redirect(...)跳转到另一个操作,以避免数据在“刷新”时被重新提交。
然后还要设置页面过期时间,以便“返回”按钮无效: https://dev59.com/kW435IYBdhLWcg3wigux#5352953

4
你提出了错误的问题。不要试图在客户端禁用“返回”操作。这将注定失败;你可能可以增加一些阻力,但你永远无法赢得这场斗争。相反,你应该重新编写具体的页面,使其只处理一次信用卡信息。你应该在服务器上“记住”已经处理过的信用卡信息,因此如果用户返回到页面重新提交信息,你只需给他们一个错误消息,说“你已经提交了这些信息,不能再次提交此请求”。
现在,有几种实现这个目标的方法,有些比其他方法更好,但这就是你需要努力达成的目标。
其中一种方法是去到每个将用户重定向到信用卡表单的页面,在提交请求之前添加一些内容到用户的会话中(即“pendingCreditCardSubmission”=true)。一旦他们提交了该请求,你就检查该会话变量。如果为真,则提交该请求并将其设置为假,如果为假或不存在,则向用户发送错误消息。

这里,送你一份升级,关于一个非常古老的答案! - Andrew Barber

2
这是我们的做法:
public class NoBackFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.ExpiresAbsolute = DateTime.Now;
        filterContext.HttpContext.Response.Expires = 0;
        filterContext.HttpContext.Response.CacheControl = "no-cache";
        filterContext.HttpContext.Response.Buffer = true;
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow);
        filterContext.HttpContext.Response.Cache.SetNoStore();
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        if (!filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.HttpContext.Request.HttpMethod != "POST" && !filterContext.Controller.ControllerContext.IsChildAction)
        {
            var after = filterContext.HttpContext.Request.RawUrl;
            var session = GetSession(filterContext);
            if (session["Current"] != null)
            {


                if (session["Before"] != null && session["Before"].ToString() == after)
                    filterContext.HttpContext.Response.Redirect(session["Current"].ToString());
                else
                {
                    session["Before"] = session["Current"];
                    session["Current"] = after;
                }
            }
            else
            {
                session["Current"] = after;
            }
        }
        base.OnActionExecuting(filterContext);

    }

    private HttpSessionStateBase GetSession(ActionExecutingContext context)
    {
        return context.HttpContext.Session;
    }

}

接下来,您可以将其实施到一般范围或控制器范围中。


1
自从这个问题被提出以来已经很久了,但我的修复方法是在WebPageController类上方添加[NoCache]。
 [NoCache]
public class WebPageController : Controller
{
    public JsonResult JsonError(Exception exception)
    {
        if (exception == null) throw new ArgumentNullException("exception");

        Response.StatusCode = 500;

        return new JsonResult
        {
            JsonRequestBehavior = JsonRequestBehavior.AllowGet,
            Data = new
            {
                error = true,
                success = false,
                message = exception.Message,
                detail = exception.ToString()
            }
        };
    }

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接