1. 程式人生 > >JS實現註冊登入傳送簡訊驗證碼動態顯示60S倒計時完整案例

JS實現註冊登入傳送簡訊驗證碼動態顯示60S倒計時完整案例

通常在web專案中都會遇到賬戶註冊或者忘記密碼時需要傳送簡訊驗證碼的功能,雖然說這種功能很常見,但是實際開發過程中很多人還會遇到不少坑。筆者經過整理把最近專案中的用到的這個傳送簡訊驗證碼動態顯示60S倒計時的完整實現過程分享給廣大開發者朋友。

1、頁面傳送簡訊驗證碼的表單

<div class="form-group">
    <div class="col-xs-6 col-sm-7 col-md-7 col-lg-7" >
       <input type="text"  id="userPhone" class="form-control" placeholder="請輸入手機號碼">
    </div>
    <div class="col-xs-6 col-sm-5 col-md-5 col-lg-5" style="justify-content:flex-end;display: flex;">
       <button type="button" class="btn btn-info"  id="second">點選獲取驗證碼</button>
    </div>
</div>
<div class="form-group">
    <input type="text" name="securityCode" class="form-control"  placeholder="請輸入驗證碼">
</div>

2、傳送簡訊驗證碼的JS處理邏輯

<script type="text/javascript">
        $("#second").click(function (){
            sendyzm($("#second"));
        });
        //用ajax提交到後臺的傳送簡訊介面
        function sendyzm(obj){
            var phone = $("#userPhone").val();
            var result = isPhoneNum();
            if(result) {
                $.ajax({
                    url:"http://localhost:8085/my/sendYzm",
                    data:{phone:phone},
                    dataType:"json",
                    type:"post",
                    async : false,
                    cache : false,
                    success:function(res){
                        debugger;
                        if(res){
                            alert("驗證碼傳送成功");
                        }else{

                        }
                    },
                    error:function(){
                        alert("驗證碼傳送失敗");
                    }
                })
                setTime(obj);//開始倒計時
            }
        }

        //60s倒計時實現邏輯
        var countdown = 60;
        function setTime(obj) {
            if (countdown == 0) {
                obj.prop('disabled', false);
                obj.text("點選獲取驗證碼");
                countdown = 60;//60秒過後button上的文字初始化,計時器初始化;
                return;
            } else {
                obj.prop('disabled', true);
                obj.text("("+countdown+"s)後重新發送") ;
                countdown--;
            }
            setTimeout(function() { setTime(obj) },1000) //每1000毫秒執行一次
        }


        //校驗手機號是否合法
        function isPhoneNum(){
            var phonenum = $("#userPhone").val();
            var reg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
            if(!reg.test(phonenum)){
                alert('請輸入有效的手機號碼!');
                return false;
            }else{
                return true;
            }
        }
    </script>

3、後臺傳送簡訊驗證碼介面(呼叫第三方簡訊服務商的發簡訊介面,各個服務商的發簡訊介面大同小異)

    @RequestMapping(value = "/sendYzm", method= RequestMethod.POST)
    @ResponseBody
    public Boolean sendYzm(String phone,HttpServletResponse res) {
        Boolean  flag = true;
        if (!DXUtil.isPhone(phone)) {
            flag = false;

        } else {
            String code = (System.currentTimeMillis() + "").substring(7);
            menuCache = CacheManager.getInstance().getCache("codeCache");
            menuCache.put(new Element(phone,code));
            DXUtil.getRequest2(phone, code);
        }
        res.setHeader("Access-Control-Allow-Origin", "*");
        return flag;
    }

這裡用到了ehcache,根據時間戳生成隨機驗證碼,然後把驗證碼放進快取,當頁面提交表單時,表單提交過來的驗證碼和從快取裡取到的驗證碼進行對比驗證。需要注意的一句程式碼:res.setHeader("Access-Control-Allow-Origin", "*");加上這句程式碼是為了解決跨域問題

如果不加這句程式碼,瀏覽器頁面的js會報下面這個錯誤提示

No 'Access-Control-Allow-Origin' header is present on the requested resource.

這是由於當使用ajax訪問遠端伺服器時,會涉及到跨域問題,導致請求失敗。這是出於安全的考慮,預設禁止跨域訪問導致的。

常用的解決方案有兩種,可以分為客戶端解決方案和伺服器端解決方案。這裡講一下服務端解決方案:

在服務端的filter或者servlet裡面新增 
response.setHeader("Access-Control-Allow-Origin", "*"); 
“Access-Control-Allow-Origin”表示允許跨域訪問,“*”表示允許所有來源進行跨域訪問,這裡也可以替換為特定的域名或ip

最終介面效果如下:

點選前:點選後倒計時:

以上程式碼就是動態傳送簡訊驗證碼後60秒倒計時功能的完整實現過程,歡迎各位朋友一起交流。筆者電話(微信18629374628)