在進行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開發中必備的技巧。
(博主學疏才淺,技術鑽研不精,望勿打臉,在此謝過各位!)