【學習筆記】Web開發中防止頁面刷新後表單重複提交,表單Token設置示例

在進行Web頁面開發時,通常會使用表單提交數據得到服務器反饋,但是也通常會碰到這樣一種情況,表單提交後,反饋的數據也拿到了,一會後因爲某些原因需要刷新當前網頁,但是又不想再一次提交表單,也就是說,刷新頁面時,不再一次提交表單,只能用戶自己點提交按鈕後才能提交表單,那麼怎麼實現了,無論GET還是POST都會緩存表單信息,那麼,我們可以增加一個表單token來實現這一需求。

1. 前端實現如下
<form action="/Search" method="GET" id="search-form" onsubmit="return generateToken()">
    <input type="text" id="keyword" name="keyword"/>
    <input type="hidden" name="token" id="token" value=""/>
    <input type="submit"/>
</form>

如上所示,增加了一個hidden域存儲token參數,而點擊提交表單後,則由generateToken方法產生一個動態隨機的token同時提交進服務器,下面我們來看generateToken方法的實現

function generateToken(){
    var date=new Date();
    var seed=""+date.getTime()+date.getYear()+date.getMonth()+date.getDate();
    var token="";
    var temp;
    for(var i=0,n=seed.length;i<n;i++){
        temp=parseInt(seed.substring(i,i+1));
        token+=String.fromCharCode(65 + temp);
    }
    $(".nav #token").val(token);
    if($(".nav #token").val()==token){
        return true;
    }
    return false;
}

js使用了當前時間+年+月+日爲基數種子,然後分別轉爲對應的字母,當然也可以直接使用數字,生成token後,賦值給hidden域,同時判斷一次hidden域的值是否和生成的token一致(看似多餘,實則防止賦值失敗的情況)。

2. 後臺服務器實現(Java)
@RequestMapping("/Search")
    public ModelAndView searchView(String keyword,Page page,String token,HttpSession session){
        ModelAndView model=new ModelAndView("Search");
        if(token==null){
            return model;
        }
        String lastToken=(String) session.getAttribute("searchFormToken");
        if(lastToken==null||!lastToken.equals(token)){
            searchByKeyword(keyword,page,session);
            session.setAttribute("searchFormToken", token);
        }
        return model;
    }

    @SuppressWarnings("unchecked")
    @RequestMapping("/Search/Keyword")
    @ResponseBody
    public Map<String,Object> searchByKeyword(String keyword,Page page,HttpSession session){
        //如果沒有關鍵詞,則默認搜索全部
        if(keyword==null){
            keyword="";
        }
        /**
         * 設置當前請求頁碼以及單頁最大顯示數,防止前段錯誤操作
         */
        page.setCurrent(page.getCurrent()==0?1:page.getCurrent());
        page.setMax(page.getMax()==0?15:page.getMax());
        session.setAttribute("searchKeyword", keyword);
        Map<String,Object> result=videoService.listSimpleInfoByKeyword(keyword, page);
        session.setAttribute("searchResult", result);
        session.setAttribute("searchPage", page);
        System.out.println(session.getAttribute("searchKeyword"));
        return result;
    }

提交表單後,服務器返回搜索頁面,提交判斷當前session中存儲的search token是否與表單提交的token一致,如果一致,表示這個表單已經處理過了,不再處理此表單,如果不一致,則處理此表單並存儲表單token,防止之後的重複提交。(由於用的是近期使用的項目代碼,所以細節不用糾結,只需要在意searchView方法中處理token的步驟即可)。

結語

防止表單提交的技術有很多,包括前端禁止提交,以及判斷URL等操作,本文只是簡述了其中的token設置方法,是較爲簡單的實現,除此之外,現在的很多框架也包含了防止重複表單的實現。
防止表單重複提交的好處有很多,重複提交註冊,提交登錄等都需要檢測重複提交,所以掌握這些方法是Web開發中必備的技巧。
(博主學疏才淺,技術鑽研不精,望勿打臉,在此謝過各位!)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章