ASP.NET中记录插入后如何防止浏览器回退显示旧值
ASP.NET 表单提交后回退显示敏感输入值的解决问题
问题描述
在ASP.NET项目中,订单页收集信用卡号这类敏感信息,插入数据后跳转至确认页。用户点击浏览器回退按钮时,会回到订单页并显示之前输入的信用卡号,需避免该情况。
现有代码示例
OrderPage.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="OrderPage.aspx.vb" Inherits="OrderPage" %> <!DOCTYPE html> <html lang="en"> <head runat="server"><title>Order</title></head> <body> <form id="form1" runat="server" class="container"> <h1>Order Item</h1> <asp:FormView ID="FormView1" runat="server" DefaultMode="Insert" DataKeyNames="OrderId" DataSourceID="SqlDataSource1"> <InsertItemTemplate> CreditCard:<br /> <asp:TextBox ID="TextBoxCreditCard" runat="server" Text='<%# Bind("CreditCard") %>' /><br /> <asp:LinkButton ID="ButtonInsert" runat="server" CausesValidation="True" CommandName="Insert" Text="Insert" /> </InsertItemTemplate> </asp:FormView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ConnectionStrings:MyString %>" InsertCommand="INSERT INTO [Order] ([CreditCard]) VALUES (@CreditCard)"> <InsertParameters> <asp:Parameter Name="CreditCard" Type="String" /> </InsertParameters> </asp:SqlDataSource> </form> </body> </html>
OrderPage.aspx.vb
Partial Class OrderPage Inherits System.Web.UI.Page Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load Response.Buffer = True Response.ExpiresAbsolute = Now() Response.Expires = -1 Response.CacheControl = "no-cache" If Not Page.IsPostBack = True Then End If End Sub Private Sub FormView1_ItemInserted(sender As Object, e As FormViewInsertedEventArgs) Handles FormView1.ItemInserted Response.Redirect("ConfirmPage.aspx?m-1") End Sub End Class
ConfirmPage.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ConfirmPage.aspx.vb" Inherits="ConfirmPage" %> <!doctype html> <html lang="en"> <head runat="server"><title>Confirmed</title></head> <body> <form id="form1" runat="server"> <h1>Success</h1> </form> </body> </html>
ConfirmPage.aspx.vb
Partial Class ConfirmPage Inherits System.Web.UI.Page Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load Call PreventBackButtonMethods(MyMethod:=2) End Sub End Class
已尝试的缓存清除方法(均无效)
- 方法1:
Response.Buffer = True Response.ExpiresAbsolute = DateTime.Now.AddSeconds(-1) Response.Expires = 0 Response.CacheControl = "no-cache" - 方法2:
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1)) Response.Cache.SetCacheability(HttpCacheability.NoCache) Response.Cache.SetNoStore() - 方法3:
Response.Cache.SetNoStore() Response.Cache.AppendCacheExtension("no-cache") Response.Expires = 0
注意事项
- 无需禁用回退按钮,仅需清除回退时显示的输入值;
- 优先选择ASP.NET后端方案(避免JS禁用或页面闪烁问题),若只能用JS也可接受;
- 尝试过Session变量但无效,因点击回退不会触发页面事件。
解决方案
方案1:ASP.NET后端完整缓存控制(推荐)
浏览器回退显示的是本地缓存页面,需强制浏览器重新向服务器请求页面,而非使用缓存。需为订单页和确认页同时设置完整的缓存禁用头:
修改OrderPage的Page_Load方法:
Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load ' 完整禁用缓存的响应头设置 Response.Cache.SetCacheability(HttpCacheability.NoCache) Response.Cache.SetNoStore() Response.Cache.SetExpires(DateTime.UtcNow.AddSeconds(-1)) Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches) Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate") If Not Page.IsPostBack Then ' 初始化表单为插入模式,确保回退加载时表单为空 FormView1.DefaultMode = FormViewMode.Insert ' 手动清空信用卡输入框 Dim txtCreditCard As TextBox = CType(FormView1.FindControl("TextBoxCreditCard"), TextBox) If txtCreditCard IsNot Nothing Then txtCreditCard.Text = String.Empty End If End If End Sub
修改ConfirmPage的Page_Load方法:
Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load ' 同样设置缓存禁用头,避免确认页被缓存 Response.Cache.SetCacheability(HttpCacheability.NoCache) Response.Cache.SetNoStore() Response.Cache.SetExpires(DateTime.UtcNow.AddSeconds(-1)) Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches) Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate") End Sub
原理:通过完整的缓存禁止头,让浏览器无法缓存订单页和确认页。用户回退时,浏览器会重新请求订单页,此时页面重新初始化,表单为空。
方案2:优化Post/Redirect/Get (PRG) 模式
当前已使用PRG模式,可在跳转时添加随机参数,进一步避免确认页被缓存:
Private Sub FormView1_ItemInserted(sender As Object, e As FormViewInsertedEventArgs) Handles FormView1.ItemInserted ' 添加随机参数,确保确认页URL唯一 Response.Redirect($"ConfirmPage.aspx?t={DateTime.Now.Ticks}") End Sub
方案3:JavaScript辅助方案(后端方案无效时补充)
若后端缓存控制在部分浏览器中仍不生效,可添加JS代码清空表单并监听回退事件:
在OrderPage的head标签中添加:
<script> // 页面加载时清空信用卡输入框 window.addEventListener('load', function() { const creditCardInput = document.getElementById('<%= TextBoxCreditCard.ClientID %>'); if (creditCardInput) creditCardInput.value = ''; }); // 监听浏览器回退事件,强制从服务器重新加载页面 window.addEventListener('popstate', function() { window.location.reload(true); }); </script>
注意:该方案依赖JavaScript,若用户禁用JS则失效,建议作为后端方案的补充。
内容的提问来源于stack exchange,提问作者ptownbro
相关产品推荐
相关产品推荐

