chenjh 2019-07-01
Node.js
的去寻找引入的依赖时,如果是Node自带的模块,比如fs文件模块,只需要填写fs即可。如果是自己定义的模块,那么需要加入./(使用相对路径),暴露接口使用exports
或者module.exports
import * from url
的引入依赖,需要填写完整的相对路径,否则是找不到模块的,暴露接口使用export
.TypeScript
需要下一些包去支持,比如express
框架这些,还有一些支持内置对象的包:"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()
)ejs
渲染的核心技巧是渲染数据的指定时先发送一个空的对象到后端,再根据需求逻辑指定
对象属性和内容,最后还是传输那个对象回来。避免了
传送过多的对象,代码看起来很复杂
HTML
结构,'这是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('服务器连接成功'); }; });
res.end / send / render
后面再写逻辑也不会执行了,因为已经返回响应。cookie
的使用我们需要依赖第三方中间件res.render()
里面是写ejs渲染的文件,所以可以不用写ejs的后缀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操作,后台逻辑。(核心)CRUD
操作全部依赖模型对象来执行。如果这时候去 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;
天坑
需要注意限制对象一旦生成那么无法改变,除非删除数据库
'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文件中的格式有三种 <% data %>
里面可以写任意代码 <%= data %>
里面写的代码最终会转义后再出现(推荐) <%- data %>
里面写的代码最终不会转义后就出现(不安全)'index.ejs ' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1>欢迎来到首页</h1> <a href="http://localhost:8080/login">登陆</a> <a href="http://localhost:8080/register">注册</a> <a href="http://localhost:8080/usercenter">个人中心</a> </body> <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script> <script> </script> </html> ------- 'login.ejs' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form method="post" action="/login"> <label for="username">用户名</label> <input type="text" name="username" value=<%= err.username %>><%= err.usernameloginerr %> <br /> <label for="password">密码</label> <input type="password" value="" name="password"> <input type="submit" id="sub"> </form> <a href='/reset'>找回密码</a> </body> <script> </script> </html> ------------ 'register.ejs' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form method="post" action="/register"> <label for="usern ame">用户名</label> <input type="text"name="username" value= <%= err.username %> > <%= err.usernamereerr %></br> <label for="password">密码</label> <input type="password" value="" name="password"> <%= err.passworderr %></br> <label for="repassword">再次确认密码</label> <input type="password" value="" name="repassword"> <%= err.repassworderr %></br> <label for="email">邮箱</label> <input type="text" name="email" value= <%= err.email %> > <%= err.emailerr %></br> <input type="submit"> </form> </body> </html> ----------- 'reset.ejs' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form method="post" action="/reset"> <label for="usern ame">您注册的用户名</label> <input type="text" name="username" value=<%= err.username %>> <%= err.usernamereerr %></br> <label for="password">重置后的密码</label> <input type="password" value="" name="password"> <%= err.passworderr %></br> <label for="repassword">请再次确认密码</label> <input type="password" value="" name="repassword"> <%= err.repassworderr %></br> <label for="email">您的注册邮箱</label> <input type="text" name="email" value=<%= err.email %>> <%= err.emailerr %></br> <input type="submit"> </form> </body> </html> ------ 'usercenter.ejs' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1>欢迎来到个人中心</h1> <a href="/index">返回主页</a> </body> </html> ------
TypeScript
重构项目的源码,目前还需要调试。运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算。以上实例中 7、5 和 12 是操作数。关系运算符用于计算结果是否为 true 或者 false。逻辑运算符用于测定变量或值之间的逻辑。