JavaScript圖形驗證碼的實現

廢話不多說,先看圖
在這裏插入圖片描述在這裏插入圖片描述
這種圖形驗證碼很高效簡潔,使用爬蟲是有較大難度的爬取網站信息的。
而且這種圖形驗證碼的應用場景非常廣,可用在登錄註冊等等需要上傳信息的地方。
現在直接上代碼

var str='';
GetCode();
function GetCode() {
    str='';
    var nums = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
    ];//驗證碼字符串
    var CodeCanvas;
    var CodeCanvasDocument;
    CodeCanvas=document.getElementById('mycanvas');//獲取畫布元素
    CodeCanvasDocument=CodeCanvas.getContext("2d");//創建context對象
    CodeCanvasDocument.fillStyle = "cornflowerblue"; //畫布填充色
    CodeCanvasDocument.fillRect(0,0,CodeCanvas.width,CodeCanvas.height);//清空畫布,重設大小即清空畫布
    CodeCanvasDocument.fillStyle="white";
    CodeCanvasDocument.font="25px Arial";//設置字體
    var rand = new Array();
    var x = new Array();
    var y = new Array();
    var num;
    for (var i = 0;i<4;i++){
        rand.push(rand[i]);//向數組裏面添加新的元素
        change();
        function change() {
            num = Math.floor(Math.random() * 100);//創建隨機數值,隨機指向驗證碼字符串
            if (num>61){/*因爲驗證碼字符串裏面只有62個字符,這個隨機數很有可能超過62,這就要重新更新生成*/
                change();/*調用自身*/
            }
        }
        rand[i]=nums[num];//取得隨機數指向的驗證碼字符串
        str+=rand[i];
        x[i] = i * 20 + 20;//設置寫在畫布上的隨機字符的字符間隔
        y[i] = Math.random() * 20 +50;//設置寫在畫布上的隨機字符的隨機高度
        rand[i]=rand[i].toUpperCase();//轉大寫
        CodeCanvasDocument.fillText(rand[i], x[i], y[i]);//將字符串寫入畫板
    }
    //轉大寫
    str=str.toUpperCase();
    //md5加密
    str=hex_md5(str);
    //隨機畫五條線
    for(j = 0;j <= 4;j++){

        Drawline(CodeCanvas, CodeCanvasDocument);
    }
    //隨機畫25個點
    for(j=0;j<=25;j++)
    {

        drawDot(CodeCanvas,CodeCanvasDocument);
    }
    Image(CodeCanvas);
}
//劃線函數
function Drawline (canvas, context) {
    context.moveTo(Math.floor(Math.random() * canvas.width), Math.floor(Math.random() * canvas.height)); //隨機線的起點x座標是畫布x座標0位置,y座標是畫布高度的隨機數
    context.lineTo(Math.floor(Math.random() * canvas.width), Math.floor(Math.random() * canvas.height)); //隨機線的終點x座標是畫布寬度,y座標是畫布高度的隨機數
    context.lineWidth = 2; //線寬
    context.strokeStyle = 'rgba(50,50,50,0.3)'; //隨機線描邊屬性
    context.stroke(); //描邊,即起點描到終點
}
// 隨機點(其實就是畫1px像素的線)
function drawDot (canvas, context) {
    var px = Math.floor(Math.random() * canvas.width);
    var py = Math.floor(Math.random() * canvas.height);
    context.moveTo(px, py);
    context.lineTo(px + 1, py + 1);
    context.lineWidth = 3;
    context.stroke();
}
function chang(CodeCanvasDocument,CodeCanvas){
    str_=document.getElementById('cod').value;
    str_=str_.toUpperCase();//轉大寫;
    //加密
    str_=hex_md5(str_);


    if(str_!=str){
        alert("驗證碼錯誤");
        /* Image(CodeCanvas);*/
        resetCode();
    }
    else{
        alert("驗證碼正確");
    }
}
function Image(CodeCanvas) {
    document.getElementById('mycanvas').style.display="none";
    var image = document.getElementById("code_img");
    image.src = CodeCanvas.toDataURL("image/png");
}
document.getElementById('code_img').οnclick=function(){
    resetCode();
};
document.getElementById('FB').οnclick=function (CodeCanvasDocument,CodeCanvas) {
    chang(CodeCanvasDocument,CodeCanvas);
};
function resetCode () {
    $('#mycanvas').remove();
    $('#code_img').before('<canvas width="200" height="100" id="mycanvas"></canvas>')
    verVal =  GetCode();
}

 我們一步一步講解

首先設置一個空的字符串,這個字符串的作用後面再講解,然後調用驗證碼函數主體部分,先設置一個數組 nums,把10個字母和26個小寫26個大寫字母當做這個數組的值,然後就是最重要的部分了,我們驗證碼用的是html5標準中的canvas畫圖控件,具體請參考w3c和菜鳥教程,這裏不再贅述。

   我們先獲取canvas畫布元素,再通過

CodeCanvasDocument=CodeCanvas.getContext("2d");

這句話來創建元素,再設置字體,背景顏色,設置大小,這個fillstyle前兩個值是畫布起始座標,後兩個值是寬度與高度,

創建並設置好了畫布以後,我們要做的就是隨機生成驗證碼,

我們先常見三個數組,for循環裏面的4是輸出多少位驗證碼,我設置的是4位,大家可以進行更改,rang.push是先數組裏面添加新的元素,這裏由於JavaScript的弱類型可以忽略,然後執行驗證碼輸出函數,我們先創造一個隨機變量,math.random()的作用是輸出一個0-1的僞隨機數,我們將它乘100,就得到了一個小數點前面有兩位數,小數點後面有若干數的隨機數,然後通過math.floor()來獲得整數部分,這樣就得到了一個隨機的兩位數,然後我們再判斷這個數是否大於61,因爲驗證碼數組裏面只有62個數,而數組下標是從0開始,所以先進行判斷是否大於61,如果大於,則重新執行這個驗證碼函數,直到小於61爲止,當獲得了一個小於61的隨機數,就把這個數當做數組的下標進行取值,並將得到的值賦值給rand[i],這裏的i是循環變量,str再加等於這個rand[i]來獲取循環完成後的字符串,然後就設置寫在畫布上的隨機字符串的字符間隔,這裏可以根據需要更改,然後就是寫在畫布上的字符的高度,這裏設置一個隨機值,當然這個隨機值也就無所謂怎麼寫了,最後轉大寫,這樣做的目的是用戶輸入驗證碼時可以不區分大小寫,當然這一個轉大寫是不可以的,後面還要再寫其他的轉大寫,然後就是通過函數filltext()來寫在畫布上,其中第一個值是要寫在畫布上的值,第二個值是這個值在畫布上顯示的橫座標,第三個是縱座標。

當所有隨機變量都輸出完成後,我們要做的是繪製直線和原點,我們先轉大寫,再進行md5加密,然後就是調用劃線函數和畫點函數,同樣設置兩個隨機變量作爲起始點和終止點的座標,然後設置線寬和顏色,最後描邊即可,畫點就是畫像素爲1的線段,這裏不再詳述,然後幾次劃線函數或者畫點函數畫布上就有幾條線和點,當全部進行完成後,調用圖像,即把畫布轉換成圖形並隱藏畫布,先設置隱藏畫布,再獲取畫布的id,通過toDataURL("image/png")的方式轉換成圖像,並賦值給image.src,這樣就成功把圖像顯示出來。

然後就是驗證,我們已經獲取了驗證碼上的圖形信息,再獲取輸入框信息,點擊提交進行比對,成功則進行下一步,不成功則重新繪製圖像.

這裏綁定了幾個函數,當點擊圖像時重新調用畫布函數重新繪圖,點擊提交錯誤時進行繪圖,最後有一個重要的步驟,當每次需要重新繪圖時,必須先移除畫布所有節點,再添加相應的元素重新繪圖。即最後一段。

ok,大功告成,圖像驗證碼就寫到這裏,後面肯定還有許多新功能,希望有興趣的同學自行研究,有什麼好的建議或者想法,在下面留言告訴我或者加我qq1841301607,我們一起討論,接受批評和建議.

 

 

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