国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

表單防重提交詳解

Kross / 772人閱讀

摘要:注意設(shè)計(jì)模式并不適用所有的重復(fù)提交情況,比如由于服務(wù)器響應(yīng)緩慢,用戶(hù)刷新提交請(qǐng)求造成的重復(fù)提交。用戶(hù)惡意避開(kāi)客戶(hù)端預(yù)防多次提交手段,進(jìn)行重復(fù)數(shù)據(jù)提交。

表單重復(fù)提交的常見(jiàn)應(yīng)用場(chǎng)景?
1、在網(wǎng)絡(luò)延遲的情況下讓用戶(hù)又是加你點(diǎn)擊多次submit按鈕導(dǎo)致?
2、表單提交后用戶(hù)點(diǎn)擊刷新按鈕導(dǎo)致表單重復(fù)提交?
3、用戶(hù)表單提交后,點(diǎn)擊瀏覽器后退按鈕退回表單頁(yè)面后進(jìn)行再次提交

很多情況下,重復(fù)提交的數(shù)據(jù),都不是我們想要的,如訂單的提交,申請(qǐng)退款的提交等,那么如何做到防重提交呢?

下面介紹有4種方法,重點(diǎn)最后一種:

1.給數(shù)據(jù)庫(kù)所需的字段添加上唯一性約束

? ? 此方法最有效的防止了數(shù)據(jù)重復(fù)提交,但是前臺(tái)還是會(huì)出現(xiàn)重復(fù)提交的情況,后臺(tái)回報(bào)錯(cuò).

2.前端使用js在點(diǎn)擊按鈕提交后設(shè)置disable,后或者js設(shè)置一個(gè)屬性,提交前為true,提交后為false
? ? 客戶(hù)端禁用js,這種方法將無(wú)效

3.使用Post/Redirect/Get  

Post/Redirect/Get簡(jiǎn)稱(chēng)PRG,是一種可以防止表單數(shù)據(jù)重復(fù)提交的一種Web設(shè)計(jì)模式,像用戶(hù)刷新提交響應(yīng)頁(yè)面等比較典型的重復(fù)提交表單數(shù)據(jù)的問(wèn)題可以使用PRG模式來(lái)避免。例如:當(dāng)用戶(hù)提交成功之后,執(zhí)行客戶(hù)端重定向,跳轉(zhuǎn)到提交成功頁(yè)面。

   注意:PRG設(shè)計(jì)模式并不適用所有的重復(fù)提交情況,比如:

       1)由于服務(wù)器響應(yīng)緩慢,用戶(hù)刷新提交POST請(qǐng)求造成的重復(fù)提交。

       2)用戶(hù)點(diǎn)擊后退按鈕,返回到數(shù)據(jù)提交界面,導(dǎo)致的數(shù)據(jù)重復(fù)提交。

       3)用戶(hù)多次點(diǎn)擊提交按鈕,導(dǎo)致的數(shù)據(jù)重復(fù)提交。

       4)用戶(hù)惡意避開(kāi)客戶(hù)端預(yù)防多次提交手段,進(jìn)行重復(fù)數(shù)據(jù)提交。

4.使用session和注解設(shè)置令牌

所謂令牌其實(shí)就是一種標(biāo)識(shí),標(biāo)識(shí)當(dāng)前提交狀態(tài),比如以前古代打戰(zhàn)時(shí),皇帝發(fā)布命令時(shí)會(huì)給個(gè)虎符給手下的人攜帶到將軍那邊傳達(dá),而將軍手上也有皇帝給的另一半虎符,將軍一對(duì)比,果然能湊成一對(duì),就根據(jù)傳達(dá)的命令去打戰(zhàn),如果來(lái)人沒(méi)有攜帶虎符,將軍是肯定把來(lái)人砍頭的.

那么這個(gè)令牌怎么設(shè)置,下圖就是寫(xiě)這個(gè)令牌token的一個(gè)思路:

1.先寫(xiě)一個(gè)簡(jiǎn)單的注解類(lèi)


import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**

自定義一個(gè)Token注解,用于標(biāo)識(shí)需要防重提交的方法

@author ranger

*
*/
@Target(value=ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TokenForm {

//用于標(biāo)記需要防重提方法的 ,創(chuàng)建Token的屬性
boolean create() default false;
//用于標(biāo)記需要防重提方法的,刪除Token的屬性
boolean remove() default false;

}


2.在跳轉(zhuǎn)到增加頁(yè)面前,創(chuàng)建token

/**
 * 跳轉(zhuǎn)到增加頁(yè)面
 * 請(qǐng)求路徑:${pageContext.request.contextPath}/admin/toAdminAdd
 * @return
 */

@RequestMapping(value="/toAdminAdd")
@TokenForm(create=true)
public String toAdminAdd(HttpServletRequest request) {

    return "manager/adminAdd";
}


3.添加數(shù)據(jù)后刪除token
/**

 * 增加管理員
 * 請(qǐng)求路徑:${pageContext.request.contextPath }/admin/addAdmin
 * @param admin
 * @param request
 * @return
 */
@RequestMapping(value="/addAdmin")
@TokenForm(remove=true)
public String addAdmin(@RequestParam Map admin,HttpServletRequest request) {
    try {
        //將密碼Md5編碼后在插入
        admin.put("admin_pwd",Md5Utils.md5((String)admin.get("admin_pwd")) );
        
        LOGGER.debug("-增加管理員-"+admin);
        adminService.addAdmin(admin);
        request.setAttribute("admin_add_msg", "增加管理員成功");
        
    } catch (Exception e) {
        e.printStackTrace();
        request.setAttribute("admin_add_msg", "增加管理員失敗");
    }
    return "manager/adminAdd";
}

4.創(chuàng)建一個(gè)攔截器,攔截發(fā)送路徑前的token信息
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import cn.gzsxt.annotation.TokenForm;

public class TokenInterceptor implements HandlerInterceptor {

private static final Logger LOGGER = LogManager.getLogger(TokenInterceptor.class);

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
    
    //第一步:獲得調(diào)用處理方法的注解
    HandlerMethod hm=(HandlerMethod) handler;
    TokenForm tokenForm = hm.getMethodAnnotation(TokenForm.class);
    
    
    //第二步:判斷是否有Token注解
    if (tokenForm!=null) {
        HttpSession session = request.getSession();
        if (tokenForm.create()==true) {
            session.setAttribute("token", UUID.randomUUID().toString());
            LOGGER.debug("打印出來(lái)的token:"+session.getAttribute("token"));
        }
        if (tokenForm.remove()==true) {
            //判斷表單的Token與服務(wù)端的Token是否相同
            String formToken = request.getParameter("token");
            Object sessionToken = session.getAttribute("token");
            //傳遞過(guò)來(lái)的Token與服務(wù)端的Token相同,允許操作,并且刪除session的Token
            if (formToken.equals(sessionToken)){
                session.removeAttribute("token");
            }else{
                //跳轉(zhuǎn)到指定的路徑
                String invoke = request.getParameter("token.invoke");
                response.sendRedirect(request.getContextPath()+invoke);
                return false;
            }
        }
        
    }
    
    return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
    // TODO Auto-generated method stub
    
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
    // TODO Auto-generated method stub
    
}


5.前端指定提交的token和重復(fù)提交后可跳轉(zhuǎn)的地址token.invoke

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/54875.html

相關(guān)文章

  • 表單防重提交詳解

    摘要:注意設(shè)計(jì)模式并不適用所有的重復(fù)提交情況,比如由于服務(wù)器響應(yīng)緩慢,用戶(hù)刷新提交請(qǐng)求造成的重復(fù)提交。用戶(hù)惡意避開(kāi)客戶(hù)端預(yù)防多次提交手段,進(jìn)行重復(fù)數(shù)據(jù)提交。 表單重復(fù)提交的常見(jiàn)應(yīng)用場(chǎng)景?1、在網(wǎng)絡(luò)延遲的情況下讓用戶(hù)又是加你點(diǎn)擊多次submit按鈕導(dǎo)致?2、表單提交后用戶(hù)點(diǎn)擊刷新按鈕導(dǎo)致表單重復(fù)提交?3、用戶(hù)表單提交后,點(diǎn)擊瀏覽器后退按鈕退回表單頁(yè)面后進(jìn)行再次提交 很多情況下,重復(fù)提交的數(shù)據(jù),...

    Backache 評(píng)論0 收藏0
  • 連連支付注意事項(xiàng)

    摘要:異步通知和同步通知異步通知和同步通知都是支付完成的時(shí)候即時(shí)發(fā)送的。請(qǐng)務(wù)必要做好訂單成功狀態(tài)防重控制。同步返回是表單的形式請(qǐng)求,用來(lái)頁(yè)面顯示成功信息。 風(fēng)控參數(shù)風(fēng)控參數(shù)是我司風(fēng)險(xiǎn)控制系統(tǒng)用來(lái)控制用戶(hù)盜卡風(fēng)險(xiǎn),保障用戶(hù)資金安全的參數(shù),也是商戶(hù)上線之前一個(gè)重要的審核事項(xiàng),一定要傳的喲~ 如果是: 1、小額虛擬類(lèi)商戶(hù),只要傳風(fēng)控參數(shù)列表中的基本風(fēng)控參數(shù); 2、實(shí)物類(lèi)的商戶(hù),要傳文檔中基本風(fēng)控參...

    Aceyclee 評(píng)論0 收藏0
  • API設(shè)計(jì)中防重放攻擊

    摘要:數(shù)據(jù)加密是否可以防止重放攻擊否,加密可以有效防止明文數(shù)據(jù)被監(jiān)聽(tīng),但是卻防止不了重放攻擊。防重放機(jī)制我們?cè)谠O(shè)計(jì)接口的時(shí)候,最怕一個(gè)接口被用戶(hù)截取用于重放攻擊。這樣,這個(gè)請(qǐng)求即使被截取了,你也只能在內(nèi)進(jìn)行重放攻擊。 HTTPS數(shù)據(jù)加密是否可以防止重放攻擊? 否,加密可以有效防止明文數(shù)據(jù)被監(jiān)聽(tīng),但是卻防止不了重放攻擊。 防重放機(jī)制 我們?cè)谠O(shè)計(jì)接口的時(shí)候,最怕一個(gè)接口被用戶(hù)截取用于重放攻擊。重...

    vvpvvp 評(píng)論0 收藏0
  • 表單提交時(shí)編碼類(lèi)型enctype詳解

    摘要:以下引用,摘自規(guī)范的章節(jié)這不就是我們?cè)诨卣{(diào)函數(shù)里判斷返回?cái)?shù)據(jù)的類(lèi)型,并且是在請(qǐng)求頭中的那個(gè)玩意兒?jiǎn)釠](méi)錯(cuò)就是它根據(jù)規(guī)范的基礎(chǔ)數(shù)據(jù)類(lèi)型的說(shuō)明,這個(gè)指定了連接資源的屬性,同時(shí)也是的那些媒體類(lèi)型。今天掰扯完了表單提交時(shí)的編碼類(lèi)型,以及它和的關(guān)系。 很早以前,當(dāng)還沒(méi)有前端這個(gè)概念的時(shí)候,我在寫(xiě)表單提交完全不去理會(huì)表單數(shù)據(jù)的編碼,在action屬性里寫(xiě)好目標(biāo)URL,剩下的啊交給瀏覽器吧~但是現(xiàn)在,...

    jackzou 評(píng)論0 收藏0
  • JS基礎(chǔ)篇--JS之表單提交時(shí)編碼類(lèi)型enctype詳解

    摘要:格式支持比鍵值對(duì)復(fù)雜得多的結(jié)構(gòu)化數(shù)據(jù),這一點(diǎn)也很有用。例如下面這段代碼最終發(fā)送的請(qǐng)求是這種方案,可以方便的提交復(fù)雜的結(jié)構(gòu)化數(shù)據(jù),特別適合的接口。 簡(jiǎn)介 form的enctype屬性為編碼方式,常用有兩種:application/x-www-form-urlencoded和multipart/form-data,默認(rèn)為application/x-www-form-urlencoded。 ...

    ad6623 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<