MVC_防止HttpPost重複提交
重複提交的場景很常見,可能是當時伺服器延遲的原因,如購物車物品疊加,重複提交多個訂單。常見的解決方法是提交後把Button在客戶端Js禁用,或是用Js禁止後退鍵等。在ASP.NET MVC 3 Web Application中 如何去防止這類HTTP-Post的重複提交呢? 我們可以藉助Session,放置一個Token在View/Page上,然後在Server端去驗證是不是同一個Token來判斷此次Http-Post是否有效。看下面的程式碼: 首先定義一個介面,便於擴充套件。
public interface IPageTokenView { /// <summary> /// Generates the page token. /// </summary> string GeneratePageToken(); /// <summary> /// Gets the get last page token from Form /// </summary> string GetLastPageToken { get; } /// <summary> /// Gets a value indicating whether [tokens match]. /// </summary> /// <value> /// <c>true</c> if [tokens match]; otherwise, <c>false</c>. /// </value> bool TokensMatch { get; } }
定義一個Abstract Class,包含一個
public abstract class PageTokenViewBase : IPageTokenView { public static readonly string HiddenTokenName = "hiddenToken"; public static readonly string SessionMyToken = "Token"; /// <summary> /// Generates the page token. /// </summary> /// <returns></returns> public abstract string GeneratePageToken(); /// <summary> /// Gets the get last page token from Form /// </summary> public abstract string GetLastPageToken { get; } /// <summary> /// Gets a value indicating whether [tokens match]. /// </summary> /// <value> /// <c>true</c> if [tokens match]; otherwise, <c>false</c>. /// </value> public abstract bool TokensMatch { get; } }
接著是實現SessionPageTokenView型別,記得需要在驗證通過後生成新的Token,對於這個Class是把它放到Session中。
public class SessionPageTokenView : PageTokenViewBase { #region PageTokenViewBase /// <summary> /// Generates the page token. /// </summary> /// <returns></returns> public override string GeneratePageToken() { if (HttpContext.Current.Session[SessionMyToken] != null) { return HttpContext.Current.Session[SessionMyToken].ToString(); } else { var token = GenerateHashToken(); HttpContext.Current.Session[SessionMyToken] = token; return token; } } /// <summary> /// Gets the get last page token from Form /// </summary> public override string GetLastPageToken { get { return HttpContext.Current.Request.Params[HiddenTokenName]; } } /// <summary> /// Gets a value indicating whether [tokens match]. /// </summary> /// <value> /// <c>true</c> if [tokens match]; otherwise, <c>false</c>. /// </value> public override bool TokensMatch { get { string formToken = GetLastPageToken; if (formToken != null) { if (formToken.Equals(GeneratePageToken())) { //Refresh token HttpContext.Current.Session[SessionMyToken] = GenerateHashToken(); return true; } } return false; } } #endregion #region Private Help Method /// <summary> /// Generates the hash token. /// </summary> /// <returns></returns> private string GenerateHashToken() { return Utility.Encrypt( HttpContext.Current.Session.SessionID + DateTime.Now.Ticks.ToString()); } #endregion
這裡有到一個簡單的加密方法,你可以實現自己的加密方法.
public static string Encrypt(string plaintext) { string cl1 = plaintext; string pwd = string.Empty; MD5 md5 = MD5.Create(); byte[] s = md5.ComputeHash(Encoding.Unicode.GetBytes(cl1)); for (int i = 0; i < s.Length; i++) { pwd = pwd + s[i].ToString("X"); } return pwd; }
我們再來編寫一個Attribute繼承FilterAttribute, 實現IAuthorizationFilter介面。然後比較Form中Token與Session中是否一致,不一致就Throw Exception. Tips:這裡最好使用依賴注入IPageTokenView型別,增加Logging 等機制
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public sealed class ValidateReHttpPostTokenAttribute : FilterAttribute, IAuthorizationFilter { public IPageTokenView PageTokenView { get; set; } /// <summary> /// Initializes a new instance of the <see cref="ValidateReHttpPostTokenAttribute"/> class. /// </summary> public ValidateReHttpPostTokenAttribute() { //It would be better use DI inject it. PageTokenView = new SessionPageTokenView(); } /// <summary> /// Called when authorization is required. /// </summary> /// <param name="filterContext">The filter context.</param> public void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } if (!PageTokenView.TokensMatch) { //log... throw new Exception("Invaild Http Post!"); } } }
還需要一個HtmlHelper的擴充套件方法:
public static HtmlString GenerateVerficationToken(this HtmlHelper htmlhelper) { string formValue = Utility.Encrypt(HttpContext.Current.Session.SessionID+DateTime.Now.Ticks.ToString()); HttpContext.Current.Session[PageTokenViewBase.SessionMyToken] = formValue; string fieldName = PageTokenViewBase.HiddenTokenName; TagBuilder builder = new TagBuilder("input"); builder.Attributes["type"] = "hidden"; builder.Attributes["name"] = fieldName; builder.Attributes["value"] = formValue; return new HtmlString(builder.ToString(TagRenderMode.SelfClosing)); }
將輸出這類的HtmlString:
<input name="hiddenToken" type="hidden" value="1AB01826F590A1829E65CBD23CCE8D53" />
我們建立一個叫_ViewToken.cshtml的Partial View,這樣便於模組化,讓我們輕易加入到具體View裡,就兩行程式碼,第一行是擴充套件方法NameSpace
@using Mvc3App.Models; @Html.GenerateVerficationToken()
假設我們這裡有一個簡單的Login.cshtml,然後插入其中:
<form method="post" id="form1" action="@Url.Action("Index")"> <p> @Html.Partial("_ViewToken") UserName:<input type="text" id="fusername" name="fusername" /><br /> Password:<input type="password" id="fpassword" name="fpassword" /> <input type="submit" value="Sign-in" /> </p> </form>
這裡我們Post的Index Action,看Controller程式碼,我們在Index上加上ValidateReHttpPostToken的attribute.
[HttpPost] [ValidateReHttpPostToken] public ActionResult Index(FormCollection formCollection) { return View(); } public ActionResult Login() { return View(); }
相關推薦
MVC_防止HttpPost重複提交
重複提交的場景很常見,可能是當時伺服器延遲的原因,如購物車物品疊加,重複提交多個訂單。常見的解決方法是提交後把Button在客戶端Js禁用,或是用Js禁止後退鍵等。在ASP.NET MVC 3 Web Application中 如何去防止這類HTTP-Post的重複提交呢? 我們可以藉助Session,放置一
防止訂單重複提交的幾種方法
第一種辦法: var flag = false;// 在提交函式外面定義個變數防止重複提交 //提交函式 function sublimit() { if(flag){
客戶端 防止訂單重複提交 介面處理
如果是瀏覽器,可以採用session的方法 具體的做法:在伺服器端生成一個唯一的隨機標識號,專業術語稱為Token(令牌),同時在當前使用者的Session域中儲存這個Token。然後將Token傳送到客戶端的Form表單中,在Form表單中使用隱藏域來儲存這個Token,表單提交的時候連同這個
javaEE開發中使用session同步和token機制來防止併發重複提交
通常在普通的操作當中,我們不需要處理重複提交的,而且有很多方法來防止重複提交。比如在登陸過程中,通過使用redirect,可以讓使用者登陸之上重定向到後臺首頁介面,當用戶重新整理介面時就不會觸發重複提交了。或者使用token,隱藏在表單中,當提交時進行token驗證,
jsp防止按鈕重複提交
使用jquery方法: <html> <body> <form method="get" action="" target="box"> <input
如何防止使用者重複提交
在我們的應用系統中,禁止使用者做出多次提交的操作是非常有必要的,比如在B2C這樣的系統裡,假如某頁面有個去銀行結算的提交按鈕,可能因為系統或網路延遲,當用戶點選提交後,返回給使用者的依舊是未付款或等待
使用struts的token防止頁面重複提交
/* * Generated by MyEclipse Struts * Template path: templates/java/JavaClass.vtl */ package com.sunsoft.struts.action; import javax.se
防止使用者重複提交的方法
表單重複提交是在多使用者Web應用中最常見、帶來很多麻煩的一個問題。有很多的應用場景都會遇到重複提交問題,比如: 點選提交按鈕兩次。 點選重新整理按鈕。 使用瀏覽器後退按鈕重複之前的操作,導致重複提交表單。 使用瀏覽器歷史記錄重複提交表單。 瀏覽器重複的HTTP請求。 幾種防止表單重複提交的方法 1
防止頁面重複提交及後退方法
1.提交後禁用提交按鈕(大部分人都是這樣做的) 如果客戶提交後,按F5重新整理怎麼辦? 2.使用Session 在提交的頁面也就是資料庫處理之前: 資料處理完後,修改session("ok")=false。 3.資料處理成功馬上Redirect到另外一個頁面 操作後重新
防止頁面重複提交(使用UUID--Session)
uuid.jsp: <%@ page language="java" import="java.util.*,day22.UuidToken" pageEncoding="UTF-8"%> <html> <head> <
頁面按鈕防止ajax重複提交
這兩天在做一個專案,頁面互動非常多,到處都是ajax,測試時發現點選按鈕是很有可能重複請求ajax,看網上說加鎖的方法,不過我也有一個方法,不知道別人用過沒,廢話不說,我用了CSS中的pointer-events屬性,直接上JS程式碼吧; ` var
表單防止頁面重複提交方法
使用者在操作表單資料時往往會出現表單資料重複提交的問題,尤其實在Web開發中此類問題比較常見。重新整理頁面,後退操作以前的頁面,單機多次按鈕都會導致資料重複提交。此類問題是因為瀏覽器重複提交HTTP請求導致。 下面簡單介紹以防止表單資料重複提交的四種解決方案。 一、在
客戶端服務端防止使用者重複提交表單
一、什麼是表單重複提交? 當網路有延遲時,使用者提交的表單等資料還沒有完成此次提交,但使用者又多次點選提交,造成使用者資料在資料庫或儲存中被提交多次。 利用執行緒延遲,簡單模擬重複提交。 表單頁面為form.html [html] view plain
防止資料重複提交的6種方法(超簡單)!
有位朋友,某天突然問磊哥:**在 Java 中,防止重複提交最簡單的方案是什麼**? 這句話中包含了兩個關鍵資訊,第一:**防止重複提交**;第二:**最簡單**。 於是磊哥問他,是單機環境還是分散式環境? 得到的反饋是單機環境,那就簡單了,於是磊哥就開始裝*了。 話不多說,我們先來複現這個問
利用session防止表單重複提交
使用者在提交表單的過程中,由於網路等原因,可能重複點選提交按鈕,向資料庫重複寫入或者讀取資料,為了防止這種情況發生。 解決方式: 1.客戶端防表單重複提交,在前端使用javascript限制。但是在前端並不能完全限制,比如下網頁原始碼更改,重複重新整理等。 2.服務端防
springMvc 攔截器 防止重複提交
1.DispatcherServlet SpringMVC具有統一的入口DispatcherServlet,所有的請求都通過DispatcherServlet。 DispatcherServlet是前置控
Http協議與表單防止重複提交實戰解決方案
http長連線與短連線 HTTP協議與TCP/IP協議的關係 HTTP的長連線和短連線本質上是TCP長連線和短連線。HTTP屬於應用層協議,在傳輸層使用TCP協議,在網路層使用IP協議。IP協議主要解決網路路由和定址問題,TCP協議主要解決如何在IP層之上可靠的傳遞資料包
自定義註解 防止重複提交
定義註解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.a
java防止頁面重新整理重複提交
轉自:https://blog.csdn.net/JasonSSH/article/details/7528539 看了網上的,有幾種方法: 1 在你的表單頁裡HEAD區加入這段程式碼: <META HTTP-EQUIV="pragma" CONTENT="no-c
Java 使用Token令牌防止表單重複提交
Token驗證詳解 參考來源:https://blog.csdn.net/woshihaiyong168/article/details/52857479 使用Token令牌防止表單重複提交 參考來源:https://blog.csdn.net/cuiyaoqiang/article/d