1. 程式人生 > 資料庫 >node.js+express+mongodb+ajax實現註冊、登陸、驗證碼

node.js+express+mongodb+ajax實現註冊、登陸、驗證碼

完整專案在,歡迎star。

本專案借鑑了,大家也可以去star。

結果展示

實現的功能:

  • 主頁面,登陸頁面,註冊頁面
  • 註冊密碼兩次輸入
  • 驗證碼檢驗

使用的技術

  • 使用MongoDB作為後端資料庫儲存使用者資訊
  • 使用node.js部署前端
  • 採用ajax實現前端與伺服器交換資料

直接輸入網址(http://localhost:8008/)進入主介面,提示需要登陸

在這裡插入圖片描述

進入註冊介面註冊賬號

在這裡插入圖片描述

註冊成功進入主頁面

在這裡插入圖片描述

也可以從登陸介面進入
在這裡插入圖片描述

環境配置

MongoDB

在ubuntu20.04下安裝MongoDB

sudo apt-get install mongodb

在專案目錄下建立MongoDB的資料和日誌目錄

mkdir log
mkdir data

啟動MongoDB

mongod --dbpath ./data/ --logpath ./log/mongod.log --fork

檢查MongoDB是否已經啟動

ps aux|grep mongo

輸出為

在這裡插入圖片描述

說明啟動成功。

檢查MongoDB監聽的預設埠

lsof -i:27017

輸出為

在這裡插入圖片描述

和上圖的pid一致,說明埠已經被開啟。

或者在OSX上安裝MongoDB

brew tap mongodb/brew 
brew install [email protected]

啟動和關閉

brew services start [email protected]
brew services stop [email protected]

配置node.js

sudo apt-get install nodejs
sudo apt-get install npm

在專案下需要安裝的node.js模組

npm install express --save
npm install body-parser --save
npm install cookie-parser --save
npm install multer --save
npm install mongodb --save

其中

  • express是我們使用的前端框架

  • body-parser用於處理 JSON, Raw, Text 和 URL 編碼的資料。

  • cookie-parser解析Cookie

  • multer 用於處理MIME編碼的表單資料。

主要程式碼

後端

專案的後端是Express和MongoDB,在專案目錄下啟動node backend.js啟動後端。

Express

啟動Express

var express = require('express');
var app = express();

後端程式中需要處理瀏覽器的跨域請求

app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
});

設定主頁面、登入和註冊介面

app.get('/main.html', function (req, res) {
    res.sendFile(__dirname + '/' + 'main.html');
})
app.get('/login.html', function (req, res) {
    res.sendFile(__dirname + '/' + 'login.html');
})
app.get('/register.html', function (req, res) {
    res.sendFile(__dirname + '/' + 'register.html');
})

將主介面作為預設介面

app.get('/', function (req, res) {
    res.sendFile(__dirname + '/' + 'main.html');
})

為註冊和登入操作新增介面

app.post('/process_login', urlencodedParser, function (req, res) {
    var userName = req.body.userName;
    var pwd = req.body.pwd; 
    if (!userName) {
        res.json({ code: -1, message: '使用者名稱不能為空' });
    } else if (!pwd) {
        res.json({ code: -1, message: '密碼不能為空' });
    } else {
        db.searchUser({ name: userName }, function (result) {
            if (result.length > 0) {
                if (result[0].name == userName && result[0].pwd == pwd) {
                    res.json({ code: 0, message: '登入成功' }); 
                } else {
                    res.json({ code: -1, message: '使用者名稱或密碼錯誤' });
                }
            } else {
                res.json({ code: -1, message: '不存在該使用者' });
            }
        });
    }
})

app.post('/process_register', urlencodedParser, function (req, res) {
    var userName = req.body.userName;
    var pwd = req.body.pwd;
    if (!userName) {
        res.json({ code: -1, message: '使用者名稱不能為空' });
    } else if (!pwd) {
        res.json({ code: -1, message: '密碼不能為空' });
    } else {
        db.searchUser({ name: userName }, function (result) {
            if (result.length > 0 && result[0].name == userName) {
                res.json({ code: -1, message: '使用者已存在,可直接登入' });
            } else {
                // res.json({ code: -1, message: '不存在該使用者' });
                db.insertUser({ name: userName, pwd: pwd }, function (insertResult) {
                    console.log(insertResult)
                    if (insertResult.insertedCount > 0) {
                        res.json({ code: 0, message: '註冊成功' });
                    } else {
                        res.json({ code: -1, message: '註冊失敗,請重新註冊' });
                    }
                })
            }
        });
    }
})

最後是開啟後端,監聽8008

var server = app.listen(8008, function () { 
    console.log("後端啟動成功!")
})

MongoDB

建立MongoDB物件

var db = require('./db');

建立db.js檔案,編寫資料庫相關操作

通過預設埠訪問MongoDB

var mongoClient = require('mongodb').MongoClient;
var url = 'mongodb://127.0.0.1:27017/';

MongoDB會在我們進行資料路操作的時候自動建立相應的資料庫,我們只需要負責編寫插入和查詢的程式碼,資料庫的名字是login_project,下面是查詢和插入的程式碼

function searchUser(whereStr, callBack) {
    mongoClient.connect(url, { useNewUrlParser: true }, function (err, db) {
        if (err) throw err;
        var dbo = db.db('login_project');
        dbo.collection('site').find(whereStr).toArray(function (err, result) {
            if (err) throw err;
            console.log('查詢指定條件的資料...', result);
            callBack(result);
            db.close();
        })
    })
}

function insertUser(myobj, callBack) {
    mongoClient.connect(url, { useNewUrlParser: true }, function (err, db) {
        if (err) throw err;
        var dbo = db.db('login_project');
        dbo.collection('site').insertOne(myobj, function (err, res) {
            if (err) throw err;
            console.log('文件插入成功');
            callBack(res);
            db.close();
        })
    })
}

最後,允許這兩個函式被外部檔案呼叫

exports.searchUser = searchUser;
exports.insertUser = insertUser;

前端

前端主要的工作是main.htmlregister.htmllogin.html的編寫。

三個介面的公共部分是導航欄

<div id="nav">
	<ul>
		<li>
			<a href="main.html">主頁</a>
		</li>
		<li>
			<a href="login.html">登入</a>
		</li>
		<li>
			<a href="register.html">註冊</a>
		</li>
	</ul>
</div>

main.html

main.html頁面通過js通過url獲得當前的使用者名稱並給出提示

var name =  getUrlParameter('name');
console.log(name);
if(name != ""){
	document.getElementById("info").innerHTML = "當前登陸的賬號為:" + name;
}

function getUrlParameter(name){
  name = name.replace(/[]/,"\[").replace(/[]/,"\[").replace(/[]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec(window.parent.location.href );
  if( results == null ) return ""; 
  else {
  	return results[1];
  }
};

通過上面的js自動更改html中的資訊

<div class="wrapper">
  <h1 id="info"></h1>歡迎使用NJU-SE-Web系統</h1>
	<h1 id="info">請登陸!</h1>
</div>

login.html

登陸介面如下

<div class="wrapper">
	<h1>歡迎登入NJU-SE-Web系統</h1>
	<div class="form-list">
		<div class="form-item">
			<span>使用者名稱:</span>
			<input type="text" name="username" id="name" />
		</div>
		<div class="form-item">
			<span>密碼:</span>
			<input type="password" name="userpwd" id="pwd" />
		</div>
    <div class="form-item">
      <canvas id="verifi-code" style='width:110px;height:25px'></canvas>
      <input id="input-code" type="text" placeholder="請輸入驗證碼">
    </div>
		<div class="btn">
			<button onclick="submit()">登入</button>
		</div>
	</div>
</div>

使用js完成登陸後的頁面切換和資料庫查詢

function submit() {
  var name = $("#name").val().trim();
  var pwd = $("#pwd").val().trim(); 
  $.ajax({
    url: "http://127.0.0.1:8008/process_login",
    type: "post",
    data: {
      userName: name,
      pwd: pwd
    },
    success: function(res) {
      console.log(res);
      if (res.code == 0) {
        window.location.href = 'main.html?name=' + name;
      } else {
        alert(res.message);
      }
    },
    error: function(){
      console.info("網路出錯");
      alert("網路出錯,請再試一次");
    }
  })
}

其中,通過url將登陸使用者的資訊傳遞給main.html頁面。

如果ajax請求成功則頁面跳轉,如果登陸失敗則給出提示資訊。

通過js程式碼實現驗證碼生成

function createCode() {
  let code = "";
  var codeLength = 4;
  var selectChar = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9,'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');
  for (var i = 0; i < codeLength; i++) {
    var charIndex = Math.floor(Math.random() * 36);
    code += selectChar[charIndex];
  }
  return code;
}

在canvas上畫出驗證碼

function draw_canvas(code) {
  if (canvas) {
    var ctx=canvas.getContext('2d');
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.font="80px Verdana";
    ctx.strokeText(code,25,110);
    console.log("canvas 繪製完成")
  }
  else
  	console.log("沒有找到canvas")
}

編寫函式檢查字串是否相同,並給出提示

function isequal(str,str1,alert_info){
  if(str != str1){
  	alert(alert_info);
  	return false;}
  else return true;
}

submit函式中檢查

var input_code = $("#input-code").val().trim(); 
if(!isequal(code, input_code, "驗證碼錯誤")) return;

同時,需要在載入頁面時載入這個驗證碼

var canvas = document.getElementById('verifi-code');
var code = '';
window.onload = function () {
  code = createCode();
  draw_canvas(code);
}

以及支援驗證碼點選重新整理

canvas.onclick = function () {
  code = createCode();
  draw_canvas(code);
}

register.html

register.htmllogin.html大致相同,主要的區別是register.html需要對密碼進行二次驗證,在submit函式中進行檢驗

var pwd = $("#pwd").val().trim(); 
var pwda = $("#pwda").val().trim(); 
if(!isequal(pwd, pwda, "兩次輸入不一致")) return;

如果驗證通過,則向資料庫中插入資訊,如果ajax請求成功,則實現跳轉

success: function(res) {
  console.log(res);
  if (res.code == 0) {
    alert("註冊成功");
    window.location.href = 'main.html?name=' + name;
  } else {
  	alert(res.message);
  }
},