我在带有 C# 的 ASP.NET MVC 上使用 Razor。
我正在调用外部网页来处理信用卡,它会返回给我。然后我显示收据。
我想阻止他们返回上一个屏幕。
我没有像 asp 这样的底层 cs 页面,因为这些是 .cshtml 文件来获取事件。
这个收据页面是一个视图,所以我不能将 JavaScript 放在标题中,因为它会影响使用它的每个页面。
有谁知道在这种情况下我如何防止后退按钮?
我在带有 C# 的 ASP.NET MVC 上使用 Razor。
我正在调用外部网页来处理信用卡,它会返回给我。然后我显示收据。
我想阻止他们返回上一个屏幕。
我没有像 asp 这样的底层 cs 页面,因为这些是 .cshtml 文件来获取事件。
这个收据页面是一个视图,所以我不能将 JavaScript 放在标题中,因为它会影响使用它的每个页面。
有谁知道在这种情况下我如何防止后退按钮?
一种可能性是从客户端缓存中排除您不想返回的页面。这可以通过设置正确的响应标头来完成。这是一个带有[NoCache]
自定义操作过滤器的示例,您可以使用它来装饰相应的控制器操作。
首先,如果之前的页面已经向服务器投递了数据,最好Redirect(...)
在处理成功后进行另一个动作,避免在“刷新”时重新提交数据。
然后还要设置页面过期,所以后退按钮不起作用:
你问错问题了。不要尝试在客户端禁用“返回”。这注定会失败;你也许可以让它变得更难,但你永远不会赢得那场战斗。相反,您应该重新编写您拥有的特定页面,以便它只会处理信用卡一次。你应该(在服务器上)“记住”你已经处理了信用卡,这样如果用户返回页面重新提交它,你可以给他们一个错误消息,说“你已经提交了这个信息,你不能提交此请求两次”。
现在,有几种方法可以实现这一总体目标,有些方法比其他方法更好,但这是您需要努力实现的目标。
一种方法是转到将用户重定向到此信用卡表单的每个页面;就在提交请求之前向该用户的会话添加一些内容(即"pendingCreditCardSubmission" = true
)一旦他们提交了该请求,您就检查该会话变量。如果为真,则提交请求并将其设置为假,如果为假或不存在,则向用户发送错误消息。
这就是我们的做法:
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;
}
}
在此之后,您可以在通用范围或控制器范围内实现它。
很久没有问这个问题了,但我的解决方法是在 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()
}
};
}
在 MVC aspnet 框架中,您可以选择RedirectToActionPermanent
然后它告诉浏览器 301 响应代码。