资讯专栏INFORMATION COLUMN

Node.js 配合 express 框架、mongodb 实践 && [使用 T

wmui / 1758人阅读

摘要:一默认使用的模块化方案,默认是的模块化方案,两者有本质区别。的去寻找引入的依赖时,如果是自带的模块,比如文件模块,只需要填写即可。这是版本入口文件使用了两个路由器路由,分别处理和请求逻辑。核心操作全部依赖模型对象来执行。

一、Node.js默认使用commonJs的模块化方案,TypeScript默认是ES6的模块化方案,两者有本质区别。

1.Node.js的去寻找引入的依赖时,如果是Node自带的模块,比如fs文件模块,只需要填写fs即可。如果是自己定义的模块,那么需要加入./(使用相对路径),暴露接口使用exports或者module.exports

2.TypeScript的 import * from url 的引入依赖,需要填写完整的相对路径,否则是找不到模块的,暴露接口使用export .

3.Node中使用TypeScript需要下一些包去支持,比如express框架这些,还有一些支持内置对象的包:

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"
  }

 "具体还需要什么,可以上网去搜索下"
二、入口文件,我们使用 ejs 引擎渲染( res.render() )

1.Node.js使用ejs渲染的核心技巧是渲染数据的指定

2.尽量一个渲染数据对象包括所有的渲染内容

3.一个渲染对象可以有很多个属性,每次get请求

时先发送一个空的对象到后端,再根据需求逻辑指定

对象属性和内容,最后还是传输那个对象回来。避免了

传送过多的对象,代码看起来很复杂

4.渲染数据的位置在渲染的ejs文件中的放置,
如果需要样式,可以事先在HTML结构中包一层HTML结构,
然后用CSS定义好。

 "这是Node.js版本"
 
 "//入口文件使用了两个路由器路由,分别处理get和post请求逻辑。
 即使是同一个路由,但是请求方式不一样,他们的处理逻辑不会冲突"
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("端口号监听成功")
    } else {
        console.log("端口监听失败", 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("服务器连接成功");
    } else {
        console.log("服务器连接成功");
    };
});
三、get请求的路由处理模块

1.路由模块的核心,一个路由处理一个逻辑

2.res.end / send / render 后面再写逻辑也不会执行了,因为已经返回响应。

3.对于cookie的使用我们需要依赖第三方中间件

4.res.render()里面是写ejs渲染的文件,所以可以不用写ejs的后缀

5.res.redirect()里面写的是定向的那个路由,指定前往那个路由,

然后根据那个路由的逻辑处理,此时浏览器中的url会改变。这就叫重定向

"//这里我们使用了第三方中间件处理cookie并且
携带数据,大概设计思路:
1.没有登录过不能进入个人中心,会跳转到登录界面
2.登录过后会有一个免登录期限进入个人中心
3.在登录界面可以通过用户名和邮箱找回密码
4.在 Node 端处理逻辑,只有res.redirect()可以
改变浏览器的网址,切记。
5.每个路由器路由代表每个不同的逻辑
6.get模块只处理渲染哪个页面的逻辑"
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模块,处理各种数据库的CRUD操作,后台逻辑。(核心)

1.CRUD操作全部依赖模型对象来执行。

2.限制对象一旦生成那么无法改变,除非删除数据库

3.限制对象的增删改查都返回的是一个promise对象,

如果这时候去 if() 里判断,无论有什么样的结果,都是true,

而且这个 CRUD 操作都是异步,所以我们把外部函数变成 async 函数,

这样可以配合 await 实现最佳异步,还可以获取他们的返回值进行

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: "用户名或密码错", 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 = "用户名格式错误";
    }
    if (!passwordReg.test(password)) {
        err.passworderr = "密码格式错误";
    }
    if (repassword !== password) {
        err.repassworderr = "两次密码输入不一致";
    }
    if (!emailReg.test(email)) {
        err.emailerr = "邮箱格式错误";
    }
    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 = "邮箱已被注册";
        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对象和database模块 有 天坑 需要注意
限制对象一旦生成那么无法改变,除非删除数据库
"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("数据库连接成功")
            resolve()
        } else {
            console.log("数据库连接失败", err)
            reject(err)
        }
    })
})

------

"model对象模块"
 "这里定义限制对象时,一定要考虑好,
 否则数据库连接启动后,除非删除数据库,
 不然无法修改限制对象的内容!!!!"
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 的渲染数据在ejs文件中的格式有三种

1. <% data %> 里面可以写任意代码

2. <%= data %> 里面写的代码最终会转义后再出现(推荐)

3. <%- data %> 里面写的代码最终不会转义后就出现(不安全)


"index.ejs "






    
    
    
    Document


    

欢迎来到首页

登陆 注册 个人中心 ------- "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

欢迎来到个人中心

返回主页 ------
七、后期会放一波 TypeScript 重构项目的源码,目前还需要调试。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102813.html

相关文章

  • Node.js 配合 express 框架mongodb 实践 &amp;&amp; [使用 T

    摘要:一默认使用的模块化方案,默认是的模块化方案,两者有本质区别。的去寻找引入的依赖时,如果是自带的模块,比如文件模块,只需要填写即可。这是版本入口文件使用了两个路由器路由,分别处理和请求逻辑。核心操作全部依赖模型对象来执行。 一、Node.js默认使用commonJs的模块化方案,TypeScript默认是ES6的模块化方案,两者有本质区别。 1.Node.js的去寻找引入的依赖时,如果...

    null1145 评论0 收藏0
  • Node.js 配合 express 框架mongodb 实践 &amp;&amp; [使用 T

    摘要:一默认使用的模块化方案,默认是的模块化方案,两者有本质区别。的去寻找引入的依赖时,如果是自带的模块,比如文件模块,只需要填写即可。这是版本入口文件使用了两个路由器路由,分别处理和请求逻辑。核心操作全部依赖模型对象来执行。 一、Node.js默认使用commonJs的模块化方案,TypeScript默认是ES6的模块化方案,两者有本质区别。 1.Node.js的去寻找引入的依赖时,如果...

    xeblog 评论0 收藏0
  • 前端资源系列(4)-前端学习资源分享&amp;前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0
  • 前端容器化——Node.Js &amp; Mongodb

    摘要:另外,中间件还提供了诸如日志记录之类功能,便于查询任务状态以及信息。 DevOps大热,这里我们借着上线一个node中间件,简单介绍下前端容器化相关的内容 原文:http://blog.thonatos.com/dockerizing-your-frontend-project/ (很多东西还来不及写,有时间再补充吧T.T,比如:如何快速在服务器部署vpn神马の一定很有用...) In...

    luckyw 评论0 收藏0
  • 前端每周清单第 29 期:Web 现状分析与优化策略、Vue 单元测试、Headless Chrom

    摘要:前端每周清单第期现状分析与优化策略单元测试爬虫作者王下邀月熊编辑徐川前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。 showImg(https://segmentfault.com/img/remote/1460000011008022); 前端每周清单第 29 期:Web 现状分析与优化策略...

    HackerShell 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<