赞
踩
{{ include './header.html' }}
<h1>hello<h1>
{{ include './footer.html' }}
在页面中可以抽取除公共的部分,比如 header.html 、footer.html
然后在各个页面中引入我们的公共部分
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{block 'title'}}默认标题{{/block}}</title> <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css"> {{block 'head'}}{{/block}} </head> <body> {{include '../_partials/header.html'}} {{block 'body'}}{{/block}} {{include '../_partials/footer.html'}} <script src="/node_modules/jquery/dist/jquery.js"></script> <script src="/node_modules/bootstrap/dist/js/bootstrap.js"></script> {{block 'script'}}{{/block}} </body> </html>
{{extend './_layouts/home.html'}}
声明一个坑
{{block 'title'}}{{'多人博客 - 首页'}}{{/block}}
{{extend './_layouts/home.html'}} // 继承 {{block 'title'}}{{'多人博客 - 首页'}}{{/block}} // 填充 {{block 'body'}} // 个性化填充 <section class="container"> <ul class="media-list"> .... </ul> <nav aria-label="Page navigation"> ... </nav> </section> {{/block}} {{block 'script'}} <script type="text/javascript"> .... </script> {{/block}}
和python flask 中的jinja2模板语法如出一辙
win 10可以建多个桌面(哈哈哈。特别的礼物)
win + tab
客户端收到成功标识,需要自己处理
使用 blueimp-md5
var md5 = require('blueimp-md5') // md5
// 对密码进行 md5 重复加密
body.password = md5(md5(body.password))
Express框架中,默认不支持 Session 和 Cookie。我们可以使用第三方中间件:express-session 来解决
var session = require('express-session')
app.use(session({
// 配置加密字符串,它会在原有加密基础之上和这个字符串拼起来去加密,目的是为了增加安全性,防止客户端恶意伪造。盐值加密
secret: 'jjhjjhjhsdu',
resave: false,
saveUninitialized: false // 无论你是否使用 Session ,我都默认直接给你分配一把钥匙
}))
|—— app.js 项目入口文件
|—— controllers
|—— models 存储使用mongoose设计的数据模型
|—— node_modules 第三方包
|—— package.json 包描述文件
|—— package-lock.json 第三方包版本锁定文件(npm v5以后)
|—— public 静态资源
|—— README.md 项目说明文档
|—— routes 路由文件包(相当于java controller)
|____ views 存储视图目录
var express = require('express') var path = require('path') var bodyParser = require('body-parser') var session = require('express-session') var router = require('./router') var app = express() app.use('/public/', express.static(path.join(__dirname, './public/'))) app.use('/node_modules/', express.static(path.join(__dirname, './node_modules/'))) // 在 Node 中,有很多第三方模板引擎都可以使用,不是只有 art-template // ejs、jade(pug)、handlebars、nunjucks // <%%> // {{}} // h1 // div // h1 app.engine('html', require('express-art-template')) app.set('views', path.join(__dirname, './views/')) // 默认就是 ./views 目录 // 配置解析表单 POST 请求体插件(注意:一定要在 app.use(router) 之前 ) // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) // parse application/json app.use(bodyParser.json()) // 在 Express 这个框架中,默认不支持 Session 和 Cookie // 但是我们可以使用第三方中间件:express-session 来解决 // 1. npm install express-session // 2. 配置 (一定要在 app.use(router) 之前) // 3. 使用 // 当把这个插件配置好之后,我们就可以通过 req.session 来发访问和设置 Session 成员了 // 添加 Session 数据:req.session.foo = 'bar' // 访问 Session 数据:req.session.foo app.use(session({ // 配置加密字符串,它会在原有加密基础之上和这个字符串拼起来去加密 // 目的是为了增加安全性,防止客户端恶意伪造 secret: 'itcast', resave: false, saveUninitialized: false // 无论你是否使用 Session ,我都默认直接给你分配一把钥匙 })) // 把路由挂载到 app 中 app.use(router) app.listen(5000, function () { console.log('running...') })
var express = require('express') var User = require('./models/user') var md5 = require('blueimp-md5') // md5 var router = express.Router() router.get('/', function (req, res) { // console.log(req.session.user) res.render('index.html', { user: req.session.user }) }) router.get('/login', function (req, res) { res.render('login.html') }) router.post('/login', function (req, res) { // 1. 获取表单数据 // 2. 查询数据库用户名密码是否正确 // 3. 发送响应数据 var body = req.body User.findOne({ email: body.email, password: md5(md5(body.password)) }, function (err, user) { if (err) { return res.status(500).json({ err_code: 500, message: err.message }) } // 如果邮箱和密码匹配,则 user 是查询到的用户对象,否则就是 null if (!user) { return res.status(200).json({ err_code: 1, message: 'Email or password is invalid.' }) } // 用户存在,登陆成功,通过 Session 记录登陆状态 req.session.user = user res.status(200).json({ err_code: 0, message: 'OK' }) }) }) router.get('/register', function (req, res) { res.render('register.html') }) router.post('/register', function (req, res) { // 1. 获取表单提交的数据 // req.body // 2. 操作数据库 // 判断改用户是否存在 // 如果已存在,不允许注册 // 如果不存在,注册新建用户 // 3. 发送响应 var body = req.body User.findOne({ $or: [{ // mongodb的条件查找or固定语法 email: body.email }, { nickname: body.nickname } ] }, function (err, data) { if (err) { return res.status(500).json({ success: false, message: '服务端错误' }) } // console.log(data) if (data) { // 邮箱或者昵称已存在 return res.status(200).json({ err_code: 1, message: 'Email or nickname aleady exists.' }) return res.send(`邮箱或者密码已存在,请重试`) } // 对密码进行 md5 重复加密 body.password = md5(md5(body.password)) new User(body).save(function (err, user) { if (err) { return res.status(500).json({ err_code: 500, message: 'Internal error.' }) } // 注册成功,使用 Session 记录用户的登陆状态 req.session.user = user // Express 提供了一个响应方法:json // 该方法接收一个对象作为参数,它会自动帮你把对象转为字符串再发送给浏览器 res.status(200).json({ err_code: 0, message: 'OK' }) // 服务端重定向只针对同步请求才有效,异步请求无效 // res.redirect('/') }) }) }) router.get('/logout', function (req, res) { // 清除登陆状态 req.session.user = null // 重定向到登录页 res.redirect('/login') }) // router.post('/register', async function (req, res) { // var body = req.body // try { // if (await User.findOne({ email: body.email })) { // return res.status(200).json({ // err_code: 1, // message: '邮箱已存在' // }) // } // if (await User.findOne({ nickname: body.nickname })) { // return res.status(200).json({ // err_code: 2, // message: '昵称已存在' // }) // } // // 对密码进行 md5 重复加密 // body.password = md5(md5(body.password)) // // 创建用户,执行注册 // await new User(body).save() // res.status(200).json({ // err_code: 0, // message: 'OK' // }) // } catch (err) { // res.status(500).json({ // err_code: 500, // message: err.message // }) // } // }) module.exports = router
// 新建话题、删除话题、修改话题、查看话题列表。。。。
const express = require("express");
const router = express.Router();
router.get("/",function (req,res) {
res.send("话题首页页")
});
router.get("/add",function (req,res) {
res.send("添加首页")
});
router.get("/delete",function (req,res) {
res.send("删除话题")
});
module.exports = router;
const express = require("express");
const router = express.Router();
//相当于后台的路由,所有的后台处理都需要从这里经过
const user = require("./routes/user");
const topic = require("./routes/topic");
router.use("/user",user);
router.use("/topic",topic);
module.exports = router;
var mongoose = require('mongoose') // 连接数据库 mongoose.connect('mongodb://192.168.43.49/test', { useMongoClient: true }) var Schema = mongoose.Schema var userSchema = new Schema({ email: { type: String, required: true }, nickname: { type: String, required: true }, password: { type: String, required: true }, created_time: { type: Date, // 注意:这里不要写 Date.now() 因为会即刻调用 // 这里直接给了一个方法:Date.now // 当你去 new Model 的时候,如果你没有传递 create_time ,则 mongoose 就会调用 default 指定的Date.now 方法,使用其返回值作为默认值 default: Date.now }, last_modified_time: { type: Date, default: Date.now }, avatar: { type: String, default: '/public/img/avatar-default.png' }, bio: { type: String, default: '' }, gender: { type: Number, enum: [-1, 0, 1], default: -1 }, birthday: { type: Date }, status: { type: Number, // 0 没有权限限制 // 1 不可以评论 // 2 不可以登录 enum: [0, 1, 2], default: 0 } }) module.exports = mongoose.model('User', userSchema)
//动态路由 http://localhost:8001/newscontent/1243
app.get('/newscontent/:aid',function (req,res) {
//req.params获取动态路由的传值
var aid = req.params.aid; //aid = 1243
res.send("hello newscontent"+"------"+aid);
})
中间件在 Node.js 中被广泛使用,它泛指一种特定的设计模式、一系列的处理单元、过滤器和处理程序,以函数的形式存在,连接在一起,形成一个异步队列,来完成对任何数据的预处理和后处理。
就是将用户从请求到响应,分步骤进行。比如检测用户是否登录、检测RBAC权限、错误捕捉
/**
* 当请求进来,会从第一个中间件开始进行匹配(也就是说任何请求都会进入这个中间件)
* 如果匹配,则进来
* 如果请求进入中间件之后,没有调用 next 则代码会停在当前中间件
* 如果调用了 next 则继续向后找到第一个匹配的中间件
* 如果不匹配,则继续判断匹配下一个中间件
*/
/**
*
* 中间件本身是一个方法,该方法接收三个参数:
* Request 请求对象
* Response 响应对象
* next 下一个中间件
* 当一个请求进入一个中间件之后,如果不调用 next 则会停留在当前中间件
* 所以 next 是一个方法,用来调用下一个中间件的
*
*/
app.use(function (req, res, next) {
console.log('1')
next()
})
app.use(function (req, res, next) {
console.log('2')
next()
})
/**
* 除了以上中间件之外,还有一种最常用的
* 严格匹配请求方法和请求路径的中间件;
* 调用 next 方法也是要匹配的(不是调用紧挨着的那个)
* app.get
* app.post
* 前面的中间件可以向后面的中间件传值
*/
app.use(function (req, res, next) { console.log(1) req.foo='传值' next() }) // 匹配路径 app.use('/aa',function (req, res, next) { //打印传值 console.log(req.foo) next() }) // 匹配路径和请求方式 app.get('/abc', function (req, res, next) { console.log('abc') next() }) app.post('/', function (req, res, next) { console.log('/') next() })
app.get("/", function (req, res, next) {
fs.readFile('./a.txt', function(err,data){
if(err){
// 出现异常抛出去给全局错误处理中间件
next(err)
}
})
})
/ 错误处理中间
app.use((err, req, res, next) => {
res.status(500).send(err.message);
})
express配置反向代理
什么是反向代理,简单说就是页面请求某接口,将该请求转发到另一个地址去处理。
这里我们使用http-proxy模块做代理(还有http-proxy-middleware模块)。有两种配置方式具体如下:
const express = require('express'); const httpProxy = require('http-proxy'); var app = express(); //创建代理对象 let proxy = httpProxy.createProxyServer({ //代理地址为http时 target: 'http://www.xxx.com', //是否需要改变原始主机头为目标URL changeOrigin: true, //cookie的作用域 cookieDomainRewrite: { '*': proxyUri } // 当地址为https时加上秘钥和 // ssl: { // key: fs.readFileSync('server_decrypt.key', 'utf8'), // cert: fs.readFileSync('server.crt', 'utf8') // }, // if you want to verify the SSL Certs // secure: false }); //配置错误处理 proxy.on('error', function (err, request, response) { response.writeHead(500, { 'Content-Type': 'text/plain', }); response.status(500).end('服务器异常!'); }); //proxy使用第一种方式 /*app.use('/api', function(req, res){ //这里可以做处理 req.url = 'api' + req.url; proxy.web(req, res); return; })*/ //proxy第二种配置方式 app.use('/api', proxy); app.listen('3000', function () { console.log(`running express`); });
const express = require('express'); const cookie = require('cookie-parser'); var app = express(); //可以创建路由,路由对象和express对象差不多,有路由就可以分模块去写请求了 const routerTmp = express.Router(); //使用cookie中间件 routerTmp.use(cookie()); //运用 routerTmp.get('/setCookie', function(req,res){ //设置cookie,这里我们不设置签名 res.cookie('cookieID','123456'); res.end(); }); routerTmp.get('/getCookie', function(req,res){ //cookie的读取 console.log(req.cookies); res.end(); } routerTmp.get('/delCookie', function(req,res){ //删除cookie res.clearCookie('cookieID'); res.end(); } //再使用这个路由,并配置请求路由的前缀 app.use('/router',routerTmp);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。