專案規劃
- 前端頁面編寫和ajax請求
- express接收前端資料,mongoose資料庫連線驗證,登入判斷
- 對mongoose資料庫連線的封裝
這裡是我上傳的簡單的專案的github地址
前端頁面的編寫
-
註冊頁面
這裡就是簡單的編寫了個前端頁面 用到bootstrap官方演示的登入頁面
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> 複製程式碼
直接引用的bootCDN然後簡單的傳了個ajax
$(function(){ $('.btn').on('click',function(){ let username=$('#username').val(); let password=$('#password').val(); $.ajax({ type: "POST", url: "http://127.0.0.1:3000/register", dataType:'json', data:{ username, password }, success: function(response) { const result = JSON.parse( response) switch ( result.status ) { case 1: // 註冊成功 if ( confirm('恭喜您註冊成功,是否要跳轉到登入頁面') ){ setTimeout( function () { location.href = "./login.html" },2000) } break; case 2: // 使用者名稱重複了 alert('使用者名稱已經重複,請您確認後在註冊') break; } }, error: function(response) { console.log(response); } }); }) }) 複製程式碼
-
登入頁面
和註冊頁面幾乎一樣 無非就是改變了下url的地址url: "http://127.0.0.1:3000/login", 複製程式碼
然後再加入了登入的token的判斷
const token=cookieUtil.get('token');//這裡的cookieUtil是下面封裝的 if(token){ alert('檢測到已經登入,兩秒後轉到首頁'); setTimeout(function(){ location.href="./index.html"; },2000) } 複製程式碼
期間用到了自己封裝的cookie.js用來獲取和設定cookie
const cookieUtil={ get: function(key) { if (document.cookie) { //判斷是否有cookie let arr = document.cookie.split('; '); //拆分cookie for (let i = 0; i < arr.length; i++) { let item = arr[i].split('='); //拆分cookie,獲得key和value // 遍歷尋找key 返回值 if (item[0] === key) return item[1]; } return ''; //如果遍歷結束 都沒有找到 返回空字串 } }, set: function(key, value, day) { if (day) { var d = new Date(); d.setDate(d.getDate() + day); document.cookie = `${key}=${value};expires=${d};path=/`; } else { document.cookie = `${key}=${value};path=/`; } }, remove: function(key) { this.set(key, '', -1); } }; 複製程式碼
簡單的登入頁面也完成了
-
忘記密碼
這裡忘記密碼就是簡單的模擬密碼修改,從登入頁面新增一個按鈕跳轉到密碼修改頁面,
url: "http://127.0.0.1:3000/modify" //就修改下ajax請求的url而已其他都一樣 複製程式碼
現在前端的基本頁面已經做好了,開始處理後端路由。
後端請求接收以及邏輯處理
-
node.js/express基礎包配置
我這裡是直接用express-generator 需要的小夥伴可以全域性安裝
npm install express-generator -g npm install //安裝express中的json包依賴 複製程式碼
然後直接在專案檔案下開啟bash輸入
express install '專案名' -e -S (這裡的e指的是express ejs模板引擎的支援,不選的話預設jade) 複製程式碼
express安裝完之後進入資料夾 沒有全域性安裝的nodemon的小夥伴可以全域性安裝下nodemon 熱更新,不想全域性安裝的可以安裝在包依賴裡面
npm install nodemon //裝完了包依賴會顯示這樣,當然全域性安裝的就不需要執行這一步了 "dependencies": { "nodemon": "^2.0.1" } 複製程式碼
開啟package.json,找到start 修改成下面這樣
"scripts": { "start": "nodemon ./bin/www" }, 複製程式碼
然後試執行npm start 沒報錯就可以啦。
-
配置路由 先來想想我們需要配置幾個路由
- 登入
在專案資料夾中的routes路由資料夾下面建立login.js檔案
``` const express=require('express'); //引入第三方模組 const router=express.Router(); //配置路由 const jwt=require('jsonwebtoken'); //登入用的token const path=require('path'); //檔案路徑 內建模組 const fs=require('fs');//檔案操作 內建模組 const {users}=require('../database'); //後面會講到的 自定義模組 資料庫封裝 router.route('/login') //如果這裡寫了路由,那麼app.js路由組中就不必寫路由了 .post(async (req,res,next)=>{ //三個引數 請求 相應 路由中介軟體的next (async)設定es6中的generator非同步操作 let results=req.body; if(!results.token){ //如果登入沒有傳token const private_key=fs.readFileSync(path.join(__dirname,'..','rsa/private_key.pem')) //私鑰 //如果不會配置私鑰的朋友可以去檢視下npm 中jsonwebtoken手冊中 這邊配置比較麻煩 另開一貼介紹 const token =jwt.sign({username:results.username}, private_key, { algorithm: 'RS256'})//token建立 const searchitem = await users.query(results); //(await)es6中的generator非同步操作 yield res.json( //返回searchitme中的返回值 JSON.stringify({ status:searchitem.status, msg:searchitem.msg, token:searchitem.status==1 && token || '使用者名稱密碼錯誤,token不返回' })) } }) module.exports=router;//匯出自定義模組 ``` 複製程式碼
- 註冊
在專案資料夾中的routes路由資料夾下面建立register.js檔案
const express=require('express'); //引入第三方模組 const router=express.Router();//路由 const {users}=require('../database')//自定義資料庫連線 router.route('/register') //register路由 .post(async (req,res,next)=>{ //與登入同理 const results=await users.add(req.body); res.json( JSON.stringify({ status:results.status, info:results.info }) ) }) module.exports=router 複製程式碼
- 修改
在專案資料夾中的routes路由資料夾下面建立modify.js檔案
const express =require('express') const router =express.Router(); const {users} =require('../database');//這裡是引入資料庫連線自定義模組 後面會講 router.route('/modify') .post(async (req,res,next)=>{ const data =req.body; const results=await users.update(data); res.json(JSON.stringify({ status:results.status, msg:results.msg })) }) module.exports=router 複製程式碼
這樣三個子路由就建立好了 接下來去app.js中引入子路由和配置中介軟體路由組
var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); var loginRouter = require('./routes/login'); var registerRouter=require('./routes/register'); var modifyRouter=require('./routes/modify'); var cors = require('cors'); //這裡提前引入cors的包 等下要解決跨域問題 cors npm直接下 var app = express(); 複製程式碼
配置路由中介軟體
app.use(cors({ //這裡實現跨域 不太懂的可以去https://www.npmjs.com/ 看下cors手冊 "origin": "*", "methods": "GET,HEAD,PUT,PATCH,POST,DELETE", "preflightContinue": false, "optionsSuccessStatus": 200 })) app.use('/', indexRouter); //這裡都是中介軟體的路由組 '/'是路由組 如果子路由配置完 這裡就不用再配置了 app.use('/users', usersRouter); app.use('/',loginRouter); app.use('/',registerRouter); app.use('/',modifyRouter); 複製程式碼
這樣配置完後 已經可以從前端傳送資料請求然後後端接收了。只不過少了資料庫連線模組。 這裡我們使用的是mongoose模組來完成,同樣你也可以在npmjs.com中檢視手冊
mongoose實現資料庫連線
-
安裝mongoosedb模組
npm install mongodb 複製程式碼
建立database檔案模組
目錄結構分析 -
檔案分析
如果簡單的按照手冊來配置的話可以完全不用這麼麻煩,一個檔案按照手冊從資料庫連線再到文件操作 一系列流程下來最多半小時模組就完成了,但是是要有封裝思想,可能你著30分鐘寫完之後你以後再回 來看,或者在對資料維護,其實非常不方便,這時候就需要引入封裝思想
index.js 這是database的入口檔案
//引入mongoose const mongoose = require('mongoose') //引入模組 //連線資料庫 const connect=require('./connect');//資料庫連線封裝 connect(); // 建立骨架 const {users,shops}=require('./handle')//模型操作 module.exports = { //匯出 users,shops } 複製程式碼
constant.js這裡是方便線上修改的模組 ,把以後容易修改的變數值都放入這裡
const HOST='127.0.0.1' //本地伺服器域名 //const HOST ='www.baidu.com' //以後專案上線需要的定位地址方便修改 const DB_NAME=1910 //資料庫名 const DB_URL=`mongodb://${ HOST }:27017/${ DB_NAME }`; module.exports={ DB_URL } 複製程式碼
connect.js資料庫連線操作模組
const mongoose = require('mongoose'); const {DB_URL}=require('./constant.js') function connect(){ mongoose.connect(DB_URL,{ useNewUrlParser: true, useUnifiedTopology: true },err=>{ if(err){ console.log(err) }else{ console.log('資料庫連線成功'); } }) } module.exports=connect 複製程式碼
schema 資料夾
-
index.js
const userSchema = require('./userSchema') const shopSchema = require('./shopSchema') //引入模組 module.exports = { //一起匯出模組 userSchema, shopSchema } 複製程式碼
-
userSchema.js
const mongoose = require('mongoose') const userSchema=new mongoose.Schema({ username: String, password: String //這裡就是你建立mongodb 集合的欄位 這裡就可以理解為關係型資料庫裡面的建表環節 }) module.exports=userSchema 複製程式碼
-
shopSchema.js
內容同上 自己定義表就好了
model資料夾
這裡的操作很簡單 就是一個簡單的函式
index.js
const mongoose =require('mongoose');
const model = ( collectionName, schema ) => {
return mongoose.model( collectionName, schema ) //兩個引數 一個是建立集合的名稱 ,一個是傳入Schema
//可以理解為 關係型資料庫中的建立表 然後自定義表名
}
module.exports = model
複製程式碼
handle資料夾
- index.js
```
const shops =require('./shopHandler');
const users =require('./userHandler'); //匯入
module.exports={//匯出
shops,
users
}
```
複製程式碼
- shopHandler.js
const {shopSchema}=require('../schema');
const model=require('../model')
const shopModel=model('shops',shopSchema)//使用model資料夾下的函式 實現表建立
const shops = { //增刪查改
add () {},
del () {},
update () {},
query () {}
}
module.exports = shops
複製程式碼
- userHandler.js
const {userSchema}=require('../schema');
const model=require('../model')
const userModel=model('users',userSchema)
const users = {
add (data) {
return new Promise((resolved,rejected)=>{ //和之前路由子檔案 下面對應 Promise操作修改非同步操作 實現同步
userModel.find({},(err,docs)=>{
const f=docs.some(item=>data.username==item.username) //如果傳來的註冊賬戶和資料庫中的有相同的
if(f){
resolved({
status:2,
info:'使用者名稱重複'
})
}else{
const userEnity=new userModel(data)
userEnity.save(err=>{
if(err){
rejected({
status:0,
info:'註冊失敗'
})
}else{
resolved({ //返回給子路由檔案,再由子路由檔案傳給前端
status:1,
info:'註冊成功'
})
}
})
}
})
})
},
del () {},
update(data) {
return new Promise((resolved,rejected)=>{
userModel.find({username:data.username,password:data.password},(err,docs)=>{//mongodb語法
//查詢賬戶名和密碼相同的文件
if(docs.length!=0){
userModel.findById(docs[0]._id,(err,doc)=>{
doc.password=data.newpassword;
doc.save(err=>{
if(err){
rejected({
status:0,
msg:'修改失敗'
})
}else{
resolved({
status:1,
msg:'修改成功'
})
}
})
})
}else{
resolved({
status:2,
msg:'賬號或密碼不正確,無法修改'
})
}
})
})
},
query (data) {
return new Promise((resolved,rejected)=>{
userModel.find({},(err,docs)=>{
const f=docs.some(item=>(item.username==data.username&&item.password==data.password))
if(f){
resolved({
status:1,
msg:"登入成功"
})
}else{
rejected({
status:2,
msg:"登陸失敗,使用者名稱或是密碼不正確"
})
}
})
}).catch((err)=>{
return err;
})
}
}
module.exports = users
複製程式碼
這樣一個簡單的專案就完成了 。