摘要:一默認(rèn)使用的模塊化方案,默認(rèn)是的模塊化方案,兩者有本質(zhì)區(qū)別。的去尋找引入的依賴時(shí),如果是自帶的模塊,比如文件模塊,只需要填寫即可。這是版本入口文件使用了兩個(gè)路由器路由,分別處理和請(qǐng)求邏輯。核心操作全部依賴模型對(duì)象來(lái)執(zhí)行。
一、Node.js默認(rèn)使用commonJs的模塊化方案,TypeScript默認(rèn)是ES6的模塊化方案,兩者有本質(zhì)區(qū)別。
1.Node.js的去尋找引入的依賴時(shí),如果是Node自帶的模塊,比如fs文件模塊,只需要填寫fs即可。如果是自己定義的模塊,那么需要加入./(使用相對(duì)路徑),暴露接口使用exports或者module.exports
2.TypeScript的 import * from url 的引入依賴,需要填寫完整的相對(duì)路徑,否則是找不到模塊的,暴露接口使用export .
3.Node中使用TypeScript需要下一些包去支持,比如express框架這些,還有一些支持內(nèi)置對(duì)象的包:
4.github源碼下載地址
"dependencies": {
"@babel/core": "^7.4.0",
"@types/core-js": "^2.5.0",
"browserify": "^16.2.3",
"connect-mongo": "^2.0.3",
"cookie-parser": "^1.4.4",
"ejs": "^2.6.1",
"express": "^4.16.4",
"express-session": "^1.15.6",
"mongoose": "^5.4.19",
"nodemon": "^1.18.10",
"sha1": "^1.1.1"
},
"devDependencies": {
"@types/express": "^4.16.1",
"@types/node": "^11.11.4",
"ts-loader": "^5.3.3",
"ts-node-dev": "^1.0.0-pre.32",
"typescript": "^3.3.4000",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0"
}
"具體還需要什么,可以上網(wǎng)去搜索下"
二、入口文件,我們使用 ejs 引擎渲染( res.render() )
1.Node.js使用ejs渲染的核心技巧是渲染數(shù)據(jù)的指定
2.盡量一個(gè)渲染數(shù)據(jù)對(duì)象包括所有的渲染內(nèi)容
3.一個(gè)渲染對(duì)象可以有很多個(gè)屬性,每次get請(qǐng)求
時(shí)先發(fā)送一個(gè)空的對(duì)象到后端,再根據(jù)需求邏輯指定
對(duì)象屬性和內(nèi)容,最后還是傳輸那個(gè)對(duì)象回來(lái)。避免了
傳送過(guò)多的對(duì)象,代碼看起來(lái)很復(fù)雜
4.渲染數(shù)據(jù)的位置在渲染的ejs文件中的放置,
如果需要樣式,可以事先在HTML結(jié)構(gòu)中包一層HTML結(jié)構(gòu),
然后用CSS定義好。
"這是Node.js版本"
"http://入口文件使用了兩個(gè)路由器路由,分別處理get和post請(qǐng)求邏輯。
即使是同一個(gè)路由,但是請(qǐng)求方式不一樣,他們的處理邏輯不會(huì)沖突"
const express = require("express");
const db = require("./common/db");
const app = express();
const uirouter = require("./router/uirouter");
const postrouter = require("./router/postrouter");
app.set("views", "views");
app.set("view engine", "ejs");
db.then(() => {
app.use(uirouter);
app.use(postrouter);
})
app.listen(8080, err => {
if (!err) {
console.log("端口號(hào)監(jiān)聽(tīng)成功")
} else {
console.log("端口監(jiān)聽(tīng)失敗", err)
}
})
-----------------
"這是TypeScript版本"
import express from "./node_modules/@types/express/index";
import db from "./common/db1";
import uirouter from "./router/uirouter1";
import postrouter from "./router/postrouter1";
const app: any = express();
app.set("views", "views");
app.set("view engine", "ejs");
db.then((): void => {
app.use(uirouter);
app.use(postrouter);
});
app.listen(8080, (err): void => {
if (!err) {
console.log("服務(wù)器連接成功");
} else {
console.log("服務(wù)器連接成功");
};
});
三、get請(qǐng)求的路由處理模塊
1.路由模塊的核心,一個(gè)路由處理一個(gè)邏輯
2.res.end / send / render 后面再寫邏輯也不會(huì)執(zhí)行了,因?yàn)橐呀?jīng)返回響應(yīng)。
3.對(duì)于cookie的使用我們需要依賴第三方中間件
4.res.render()里面是寫ejs渲染的文件,所以可以不用寫ejs的后綴
5.res.redirect()里面寫的是定向的那個(gè)路由,指定前往那個(gè)路由,
然后根據(jù)那個(gè)路由的邏輯處理,此時(shí)瀏覽器中的url會(huì)改變。這就叫重定向
"http://這里我們使用了第三方中間件處理cookie并且
攜帶數(shù)據(jù),大概設(shè)計(jì)思路:
1.沒(méi)有登錄過(guò)不能進(jìn)入個(gè)人中心,會(huì)跳轉(zhuǎn)到登錄界面
2.登錄過(guò)后會(huì)有一個(gè)免登錄期限進(jìn)入個(gè)人中心
3.在登錄界面可以通過(guò)用戶名和郵箱找回密碼
4.在 Node 端處理邏輯,只有res.redirect()可以
改變?yōu)g覽器的網(wǎng)址,切記。
5.每個(gè)路由器路由代表每個(gè)不同的邏輯
6.get模塊只處理渲染哪個(gè)頁(yè)面的邏輯"
const { Router } = require("express");
const model = require("../common/model");
const cookieParse = require("cookie-parser");
const router = new Router();
router.use(cookieParse())
router.get("/index", (req, res) => {
res.render("index.ejs", { err: "" })
})
router.get("/", (req, res) => {
res.redirect("/index");
});
router.get("/login", (req, res) => {
res.render("login.ejs", { err: "" });
});
router.get("/register", (req, res) => {
res.render("register.ejs", { err: "" });
});
router.get("/reset", (req, res) => {
res.render("reset.ejs", { err: "" });
});
router.get("/usercenter", async (req, res) => {
const result = await model.findOne({ _id: req.cookies.userid });
if (!result) {
res.redirect("/login")
return
}
res.render("usercenter.ejs", { err: "" });
});
module.exports = router;
四、post模塊,處理各種數(shù)據(jù)庫(kù)的CRUD操作,后臺(tái)邏輯。(核心)
1.CRUD操作全部依賴模型對(duì)象來(lái)執(zhí)行。
2.限制對(duì)象一旦生成那么無(wú)法改變,除非刪除數(shù)據(jù)庫(kù)
3.限制對(duì)象的增刪改查都返回的是一個(gè)promise對(duì)象,
如果這時(shí)候去 if() 里判斷,無(wú)論有什么樣的結(jié)果,都是true,
而且這個(gè) CRUD 操作都是異步,所以我們把外部函數(shù)變成 async 函數(shù),
這樣可以配合 await 實(shí)現(xiàn)最佳異步,還可以獲取他們的返回值進(jìn)行
if 判斷。(Node.js的后端核心)
const { Router } = require("express");
const express = require("express");
const model = require("../common/model");
const cookieParse = require("cookie-parser");
const sha1 = require("sha1");
const router = new Router();
router.use(cookieParse())
router.use(express.urlencoded({ extended: true }))
router.post("/login", async (req, res) => {
const { username, password } = req.body;
const result = await model.findOne({ username, password: sha1(password) });
if (!result) {
res.render("login", { err: { usernameloginerr: "用戶名或密碼錯(cuò)", username: username } })
return;
}
const userid = result.id;
res.cookie("userid", userid, {maxAge:1000*60*10});
res.redirect("/usercenter")
return
});
router.post("/register", async (req, res) => {
const { username, password, repassword, email } = req.body;
const err = {};
const usernameReg = /^[A-Za-z0-9_]{5,10}$/;
const passwordReg = /^[A-Za-z0-9_]{5,12}$/;
const emailReg = /^w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$/;
if (!usernameReg.test(username)) {
err.usernamereerr = "用戶名格式錯(cuò)誤";
}
if (!passwordReg.test(password)) {
err.passworderr = "密碼格式錯(cuò)誤";
}
if (repassword !== password) {
err.repassworderr = "兩次密碼輸入不一致";
}
if (!emailReg.test(email)) {
err.emailerr = "郵箱格式錯(cuò)誤";
}
const usernameresult = await model.findOne({ username });
if (usernameresult) {
err.usernamereerr = "用戶名已存在";
res.render("register", { err })
return
};
const emailresult = await model.findOne({ email });
if (emailresult) {
err.emailerr = "郵箱已被注冊(cè)";
res.render("register", { err })
return
}
if (err.usernamereerr || err.passworderr || err.repassworderr || err.emailerr) {
err.username = username;
err.email = email;
res.render("register", { err })
return
}
model.create({
username: username,
password: sha1(password),
email: email
})
res.redirect("/index")
});
router.post("/reset", async (req, res) => {
const { username, password, repassword, email } = req.body;
const err = {};
const result = await model.findOne({ username, email });
if (!result) {
if (repassword !== password) {
err.repassworderr = "兩次密碼輸入不一致"
}
err.usernamereerr = "用戶名或者郵箱輸入有誤";
err.emailerr = "用戶名或者郵箱輸入有誤";
res.render("reset.ejs", { err })
return
} else {
await model.updateOne({ username, email }, { password: sha1(password) });
res.redirect("/usercenter");
return
}
})
module.exports = router;
五、工具類模塊 model對(duì)象和database模塊 有 天坑 需要注意
限制對(duì)象一旦生成那么無(wú)法改變,除非刪除數(shù)據(jù)庫(kù)
"database模塊"
const mongoose = require("mongoose");
module.exports = new Promise((resolve, reject) => {
mongoose.connect("mongodb://localhost:27017/userinfos", { useCreateIndex: true, useNewUrlParser: true });
mongoose.connection.once("open", err => {
if (!err) {
console.log("數(shù)據(jù)庫(kù)連接成功")
resolve()
} else {
console.log("數(shù)據(jù)庫(kù)連接失敗", err)
reject(err)
}
})
})
------
"model對(duì)象模塊"
"這里定義限制對(duì)象時(shí),一定要考慮好,
否則數(shù)據(jù)庫(kù)連接啟動(dòng)后,除非刪除數(shù)據(jù)庫(kù),
不然無(wú)法修改限制對(duì)象的內(nèi)容!!!!"
const { Schema, model } = require("mongoose");
const ajaxschema = new Schema({
username: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
email: {
type: String,
unique: true,
required: true
},
})
const model1 = model("userinfo", ajaxschema);
module.exports = model1;
六、 ejs 的渲染目錄
ejs 的渲染數(shù)據(jù)在ejs文件中的格式有三種
1. <% data %> 里面可以寫任意代碼
2. <%= data %> 里面寫的代碼最終會(huì)轉(zhuǎn)義后再出現(xiàn)(推薦)
3. <%- data %> 里面寫的代碼最終不會(huì)轉(zhuǎn)義后就出現(xiàn)(不安全)
"index.ejs "
Document
歡迎來(lái)到首頁(yè)
登陸
注冊(cè)
個(gè)人中心
-------
"login.ejs"
Document
><%= err.usernameloginerr %>
找回密碼
-
------------
"register.ejs"
Document
> <%= err.usernamereerr %>
<%= err.passworderr %>
<%= err.repassworderr %>
> <%= err.emailerr %>
-----------
"reset.ejs"
Document
> <%= err.usernamereerr %>
<%= err.passworderr %>
<%= err.repassworderr %>
> <%= err.emailerr %>
------
"usercenter.ejs"
Document
歡迎來(lái)到個(gè)人中心
返回主頁(yè)
------
七、后期會(huì)放一波 TypeScript 重構(gòu)項(xiàng)目的源碼,目前還需要調(diào)試。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/102813.html
摘要:一默認(rèn)使用的模塊化方案,默認(rèn)是的模塊化方案,兩者有本質(zhì)區(qū)別。的去尋找引入的依賴時(shí),如果是自帶的模塊,比如文件模塊,只需要填寫即可。這是版本入口文件使用了兩個(gè)路由器路由,分別處理和請(qǐng)求邏輯。核心操作全部依賴模型對(duì)象來(lái)執(zhí)行。 一、Node.js默認(rèn)使用commonJs的模塊化方案,TypeScript默認(rèn)是ES6的模塊化方案,兩者有本質(zhì)區(qū)別。 1.Node.js的去尋找引入的依賴時(shí),如果...
摘要:一默認(rèn)使用的模塊化方案,默認(rèn)是的模塊化方案,兩者有本質(zhì)區(qū)別。的去尋找引入的依賴時(shí),如果是自帶的模塊,比如文件模塊,只需要填寫即可。這是版本入口文件使用了兩個(gè)路由器路由,分別處理和請(qǐng)求邏輯。核心操作全部依賴模型對(duì)象來(lái)執(zhí)行。 一、Node.js默認(rèn)使用commonJs的模塊化方案,TypeScript默認(rèn)是ES6的模塊化方案,兩者有本質(zhì)區(qū)別。 1.Node.js的去尋找引入的依賴時(shí),如果...
摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒(méi)想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...
摘要:另外,中間件還提供了諸如日志記錄之類功能,便于查詢?nèi)蝿?wù)狀態(tài)以及信息。 DevOps大熱,這里我們借著上線一個(gè)node中間件,簡(jiǎn)單介紹下前端容器化相關(guān)的內(nèi)容 原文:http://blog.thonatos.com/dockerizing-your-frontend-project/ (很多東西還來(lái)不及寫,有時(shí)間再補(bǔ)充吧T.T,比如:如何快速在服務(wù)器部署vpn神馬の一定很有用...) In...
摘要:前端每周清單第期現(xiàn)狀分析與優(yōu)化策略單元測(cè)試爬蟲(chóng)作者王下邀月熊編輯徐川前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開(kāi)發(fā)教程工程實(shí)踐深度閱讀開(kāi)源項(xiàng)目巔峰人生等欄目。 showImg(https://segmentfault.com/img/remote/1460000011008022); 前端每周清單第 29 期:Web 現(xiàn)狀分析與優(yōu)化策略...
閱讀 724·2021-11-22 13:52
閱讀 1533·2021-09-27 13:36
閱讀 2834·2021-09-24 09:47
閱讀 2195·2021-09-22 15:48
閱讀 3610·2021-09-22 15:39
閱讀 1475·2019-08-30 12:43
閱讀 2929·2019-08-29 18:39
閱讀 3197·2019-08-29 12:51