10

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

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

我想阻止他们返回上一个屏幕。

我没有像 asp 这样的底层 cs 页面,因为这些是 .cshtml 文件来获取事件。

这个收据页面是一个视图,所以我不能将 JavaScript 放在标题中,因为它会影响使用它的每个页面。

有谁知道在这种情况下我如何防止后退按钮?

4

6 回答 6

15

一种可能性是从客户端缓存中排除您不想返回的页面。这可以通过设置正确的响应标头来完成。这是一个带有[NoCache]自定义操作过滤器的示例,您可以使用它来装饰相应的控制器操作。

于 2012-10-19T16:13:14.780 回答
7

首先,如果之前的页面已经向服务器投递了数据,最好Redirect(...)在处理成功后进行另一个动作,避免在“刷新”时重新提交数据。

然后还要设置页面过期,所以后退按钮不起作用:

https://stackoverflow.com/a/5352953/864763

于 2012-10-19T16:14:04.870 回答
4

你问错问题了。不要尝试在客户端禁用“返回”。这注定会失败;你也许可以让它变得更难,但你永远不会赢得那场战斗。相反,您应该重新编写您拥有的特定页面,以便它只会处理信用卡一次。你应该(在服务器上)“记住”你已经处理了信用卡,这样如果用户返回页面重新提交它,你可以给他们一个错误消息,说“你已经提交了这个信息,你不能提交此请求两次”。

现在,有几种方法可以实现这一总体目标,有些方法比其他方法更好,但这是您需要努力实现的目标。

一种方法是转到将用户重定向到此信用卡表单的每个页面;就在提交请求之前向该用户的会话添加一些内容(即"pendingCreditCardSubmission" = true)一旦他们提交了该请求,您就检查该会话变量。如果为真,则提交请求并将其设置为假,如果为假或不存在,则向用户发送错误消息。

于 2012-10-19T16:44:10.457 回答
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;
    }

}

在此之后,您可以在通用范围或控制器范围内实现它。

于 2013-09-30T19:13:47.860 回答
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()
            }
        };
    }
于 2016-08-09T18:32:21.033 回答
0

在 MVC aspnet 框架中,您可以选择RedirectToActionPermanent

然后它告诉浏览器 301 响应代码。

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.redirecttoactionpermanent?view=aspnetcore-5.0

于 2021-04-29T23:50:39.977 回答