一、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 '
<!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>
------