1. 程式人生 > 遊戲 >《艾爾登法環》武士職業演示 武力強悍爽快砍殺

《艾爾登法環》武士職業演示 武力強悍爽快砍殺

如何防止表單的重複提交

1.通過js程式碼,當用戶點選提交按鈕後,遮蔽提交按鈕使使用者無法點選提交按鈕或點選無效,從而實現防止表單重複提交。【不推薦】通過重新整理或者繞過前段頁面後仍然能夠重複提交表單

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript">
        //預設提交狀態為false
        var commitStatus = false;
        function dosubmit(){
            if(commitStatus==false){
                //提交表單後,講提交狀態改為true
                commitStatus = true;
                return true;
            }else{
                return false;
            }
        }
    </script>
</head>

<body>

<script>
    alert(dosubmit());
</script>

<form action="/path/post" onsubmit="return dosubmit()" method="post">
    使用者名稱:<input type="text" name="username">
    <input type="submit" value="提交" id="submit">
</form>
</body>
</html>

2.給資料庫增加唯一鍵約束【不推薦】,重複訪問資料庫帶來額外的負擔

alter table tableName_xxx add unique key uniq_xxx(field1, field2)

3.利用Session防止表單重複提交【推薦,但是重新整理的話是否會獲得一個新的token】

伺服器返回表單頁面時,會先生成一個subToken保存於session,並把該subToen傳給表單頁面。當表單提交時會帶上subToken,伺服器攔截器Interceptor會攔截該請求,攔截器判斷session儲存的subToken和表單提交subToken是否一致。若不一致或session的subToken為空或表單未攜帶subToken則不通過。

@RequestMapping("/form")
//開啟一個Token
@SubToken(saveToken = true)
public String form() {
  return "/test/form";
}


@RequestMapping(value = "/postForm", method = RequestMethod.POST)
@ResponseBody
//開啟Token驗證,並且成功之後移除當前Token
@SubToken(removeToken = true)
public String postForm(String userName) {
  System.out.println(System.currentTimeMillis());
  try{
	System.out.println(userName);
    Thread.sleep(1500);//暫停1.5秒後程序繼續執行
  }catch (InterruptedException e) {
    e.printStackTrace();
 }
 System.out.println(System.currentTimeMillis());
 return "1";
}

首次提交表單時session的subToken與表單攜帶的subToken一致走正常流程,然後攔截器內會刪除session儲存的subToken。當再次提交表單時由於session的subToken為空則不通過。從而實現了防止表單重複提交。

<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="/postForm">
<input type="text" name="userName">
<input type="hidden" name="subToken" value="${subToken}">
<input type="submit" value="提交">
</form>
</body>
</html>

4.使用AOP自定義切入實現

import java.lang.annotation.*;

/**
 * 避免重複提交
 * @author hhz
 * @version
 * @since
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AvoidRepeatableCommit {

    /**
     * 指定時間內不可重複提交,單位毫秒
     * @return
     */
    long timeout()  default 30000 ;

}

自定義切入點

@Aspect
@Component
public class AvoidRepeatableCommitAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * @param point
     */
    @Around("@annotation(com.xwolf.boot.annotation.AvoidRepeatableCommit)")
    public Object around(ProceedingJoinPoint point) throws Throwable {

        HttpServletRequest request  = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
        String ip = IPUtil.getIP(request);
        //獲取註解
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        //目標類、方法
        String className = method.getDeclaringClass().getName();
        String name = method.getName();
        String ipKey = String.format("%s#%s",className,name);
        int hashCode = Math.abs(ipKey.hashCode());
        String key = String.format("%s_%d",ip,hashCode);
        log.info("ipKey={},hashCode={},key={}",ipKey,hashCode,key);
        AvoidRepeatableCommit avoidRepeatableCommit =  method.getAnnotation(AvoidRepeatableCommit.class);
        long timeout = avoidRepeatableCommit.timeout();
        if (timeout < 0){
                        //過期時間5分鐘
            timeout = 60*5;
        }
        String value = (String) redisTemplate.opsForValue().get(key);
        if (StringUtils.isNotBlank(value)){
            return "請勿重複提交";
        }
        redisTemplate.opsForValue().set(key, UUIDUtil.uuid(),timeout,TimeUnit.MILLISECONDS);
        //執行方法
        Object object = point.proceed();
        return object;
    }

}

CSS選擇器

萬用字元選擇器:用*來表示,可以選擇所有元素

*{marigin: 0;
 padding: 0;
 font-size: 14px;
}

類選擇器 :類選擇器根據類名來選擇,前面以”.”來標誌,是以一獨立於文件元素的方式來指定樣式

 .demo {
 width: 200px;
 height: 200px;
 margin: 50px auto;
 background: #2DC4CB;
 }

元素選擇器:元素選擇器(標籤名選擇器),是css3選擇器中最常見而且最基本的選擇器。元素選擇器其實就是文件的元素,如html,body,p,div等等下下面例子中選擇了span元素,並設定了字型顏色為紅色。

ID選擇器:我們在類使用時是在相對應的類名前加上一個“.”號

 #demo {
 width: 200px;
 height: 200px;
 margin: 50px auto;
 background: #FF0000;
 }

HTML常用標籤:

1.段落、標題 <p></p>	<h1></h1>...<h6></h6>
用來定義網頁中的一段文字,段落與段落之間換行。
屬性:align:定義段落中的文字水平方向的對齊方式。
屬性值:left左對齊、right右對齊、center居中對齊

2.換行標籤: <br/>
指行與行之間換行,他是一個單標籤。

3.<blockquote>文欄位落縮排</blockquote>

4.列表:無需ul、有序ol
<ul type="circle"> 
         <li>列表項</li> 
         <li>列表項</li>
</ul>circle空心圓、disc實心圓、square實心方塊

5.特殊樣式
<b>加粗</b>
<i>傾斜</i>
<u>下劃線</u>
<s>刪除線</s>
<big>放大</big>
<small>縮小</small>
<strong>加強強調</strong>
<em>強調傾斜</em>

6.<img/>圖片標籤
屬性:
src:指定圖片原始檔;
alt :圖片未載入成功的提示文字;
width:指定圖片的寬度;
height:指定圖片的高度;
border:指定圖片的邊框樣式;
alghr:top/bottom/middle;圖片位於兩端文字在垂直方向的一個上/中/下的對齊方式;

7.超連結<a></a>
屬性:
href:連線地址;空連線可以用"#"代替;
target :_self/_blank;開啟方式;_self在當前頁面中開啟,_blank在新的空白視窗開啟

8.<div></div>可定義文件中的分割槽或節
<span></span> 標籤被用來組合文件中的行內元素


表格設定與樣式:
<table></table>:表格基本結構

<table>
   <caption>表格標題</caption>
  	<tr>
       	    <td>我是第一行的第一個單元格</td>
            <td>我是第一行的第二個單元格</td>
    	</tr>
   	<tr>
       	    <td>我是第二行的第一個單元格</td>
       	    <td>我是第二行的第二個單元格</td>
    	</tr>
</table>

table的屬性:width:表格的寬度 height:表格的高度 align:表格的對齊方式
tr的屬性:height:行的高度 bordercolor:邊框的顏色

表單內建部件:

單選按鈕 (checked預設)

<input type="radio" name=" " checked />  
<input type="radio" name=" " />

複選按鈕 (checked預設)

<input type="checkbox" name=" " checked />  
<input type="checkbox" name=" " />

列表框

<select size="一次顯示多少個" multiple="可多選">
<option selected>預設的下拉選單1</option>
<option>下拉選單2</option>
</select>

單行文字框

<input type="text" size="文字框顯示的長度" maxlength="最長字元數"/>

檔案域

<input type="file"/>