Express入門基礎(chǔ)(安裝+路由+模板引擎+MongoDB+nodemon+session+redis)

一份名、安裝

1婚肆、安裝nodejs
2租副、全局安裝expressexpress-generator

npm install -g express
npm install -g express-generator//最新express4.0版本中將命令工具分家出來了,所以我們還需要安裝一個(gè)命令工具

3较性、創(chuàng)建項(xiàng)目

express -e blog//-e:添加ejs模板引擎用僧,其他功能可以express -h查看

4、安裝依賴

npm i

5赞咙、運(yùn)行

npm start

打開localhost:3000,頁面顯示如下:

前臺(tái)

后臺(tái)命令行

app.js主要用于各項(xiàng)基礎(chǔ)配置

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

二责循、目錄結(jié)構(gòu)

bin:存放啟動(dòng)項(xiàng)目的腳本文件
node_modules: 存放所有的項(xiàng)目依賴庫。
public:靜態(tài)文件(css,js,img)
routes:路由文件(MVC中的C,controller)
views:頁面文件(Ejs模板)
package.json:項(xiàng)目依賴配置及開發(fā)者信息
app.js:應(yīng)用核心配置文件

三攀操、路由控制

app.js中下面兩行代碼指定路由文件院仿;
user中第一個(gè)參數(shù)指定根目錄,usersRouter文件中的路由配置都是其子路徑崔赌,例如:/users/route1意蛀、/users/route2

app.use('/', indexRouter);
app.use('/users', usersRouter);

\routes\index.js代碼

var express = require('express');
var router = express.Router();

//對(duì)應(yīng)前臺(tái)路徑:http://localhost:3000/
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

\models\users.js代碼

var mongoose = require('../db/mongooseDb.js'),
    Schema = mongoose.Schema;

var UserSchema = new Schema({          
    username : { type: String },                    //用戶賬號(hào)
    userpwd: {type: String},                        //密碼
    userage: {type: Number},                        //年齡
    logindate : { type: Date}                       //最近登錄時(shí)間
});

module.exports = mongoose.model('User',UserSchema);

\routes\users.js代碼

var express = require('express');
var router = express.Router();

//對(duì)應(yīng)前臺(tái)路徑:http://localhost:3000/users
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

更多express路由配置請(qǐng)看:https://www.expressjs.com.cn/4x/api.html#router

四、模板引擎

app.js中一下兩行代碼制定了模板文件夾和使用的模板引擎健芭。

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

常用標(biāo)簽

a县钥、<%%>標(biāo)簽里可以寫js代碼-定義變量

<% var data = 50;var hello = '<h3>hello world</h3>' %>  

b、<%=%>和<%-%> 區(qū)別 前者不會(huì)編譯,后者會(huì)編譯

<h2>data的值為 : <%=data%></h2>  
 <%=hello%><br>  
 <%-hello%>  

運(yùn)行結(jié)果:

image

c慈迈、<%include xxx%> 包含其他ejs文件,一般用于包含頭部引用和頁面相同的部分

<%include a%>//a是同目錄下的a.ejs

d若贮、<%for%>一般用于后端查詢出一段數(shù)組數(shù)據(jù),前端展示
后端虛擬數(shù)據(jù):

  req.titles = [  
    {name:'nodejs官網(wǎng)',url:'http://nodejs.org/'},  
    {name:'express官網(wǎng)',url:'http://www.expressjs.com.cn/'},  
    {name:'ejs官網(wǎng)',url:'http://www.embeddedjs.com/'},  
    {name:'javascript官網(wǎng)',url:'http://www.w3school.com.cn/js/'}  
  ];  
 res.render('ejs',req);  

前端代碼:

  <%for(var i=0; i < titles.length; i++){ var title = titles[i]; %>  
  <h3>標(biāo)題 : <%=title.name%> ,地址 : <%=title.url%> </h3>  
  <%}%>  

運(yùn)行效果:

image

e省有、<%if%> 判斷 一般都和for結(jié)合使用,也可單獨(dú)使用
后端虛擬數(shù)據(jù)

  req.numbers = [  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random()),  
    parseInt(10*Math.random())  
  ];  
  res.render('ejs',req);  

前端代碼:

  <%for(var i=0; i < numbers.length; i++){ var number = numbers[i]; %>  
  <%if(number < 5){%>  
  <h3>獲取后端值小于5,值為 : <%=number%></h3>  
  <%}else{%>  
  <h3>獲取后端值大于4,值為 : <%=number%></h3>  
  <%}%>  
  <%}%>  

運(yùn)行結(jié)果:


image

五、MongoDB數(shù)據(jù)庫

1谴麦、下載
地址1:Download Center: Community Server | MongoDB
地址2:http://dl.mongodb.org/dl/win32/x86_64
下載后運(yùn)行安裝時(shí)注意蠢沿,

image.png

2、啟動(dòng)
打開mongodb安裝目錄下bin目錄匾效,例如:C:\Program Files\MongoDB\Server\4.2\bin>舷蟀,執(zhí)行下面代碼

./mongod --dbpath D:\MongoDB\data
//這個(gè)路徑是mongodb數(shù)據(jù)庫文件存放地點(diǎn)犀呼,可自定義;
//"./"必須加什猖,win10中powershell不支持執(zhí)行mongod --dbpath D:\MongoDB\data
//D:\MongoDB\data目錄要提前創(chuàng)建好

3、訪問
進(jìn)入mongodb安裝目錄bin中妻顶,命令行執(zhí)行:./mongo魔策。
一些常用的命令:
數(shù)據(jù)庫:show dbs 匈子;use mytest ; db.dropDatabase()
集合:show collections ; db.createCollection("mycollection") ; db.mycollection.drop()
文檔:db.mycollection.find() ; db.mycollection.insert({name:"xxx"}) ; db.mycollection.remove({'name':'xxx'})
更多:https://www.runoob.com/mongodb/mongodb-query.html

推薦MongoDB的可視化工具studio-3trobo-3t闯袒,版本:robo3t-1.3.1-windows-x86_64-7419c406.exe
鏈接:https://pan.baidu.com/s/1HqyABG8gD2o_cuzXMQ44Bw
提取碼:le9q
在express中虎敦,都是基于數(shù)據(jù)模型對(duì)mongodb進(jìn)行增刪改查,所以可視化工具更多是用來查看數(shù)據(jù)

六政敢、mongoose 數(shù)據(jù)模型

直接用 node.js 也可以連接數(shù)據(jù)庫進(jìn)行讀寫其徙,但很多插件除了封裝這個(gè)基本功能之外,還提供了很多其他的服務(wù)堕仔。對(duì)于 MongoDB擂橘,我不會(huì)使用原生 node 去操作,而是選了 mongoose 這個(gè)插件摩骨。mongoose 官網(wǎng): https://mongoosedoc.top/

1通贞、安裝 mongoose

npm install mongoose --save-dev

2、根目錄創(chuàng)建數(shù)據(jù)庫配置文件db\config.js

module.exports = {
    mongodb_url: "mongodb://localhost:27017/blog"
}

3恼五、根目錄創(chuàng)建數(shù)據(jù)庫連接文件db\mongooseDb.js

let mongoose = require("mongoose");
let config = require("./config");

var DB_URL = config.mongodb_url;
mongoose.Promise = global.Promise;
/**
 * 連接
 */
mongoose.connect(DB_URL);

/**
  * 連接成功
  */
mongoose.connection.on('connected', function () {
    console.log('Mongoose connection success to ' + DB_URL);
});

/**
 * 連接異常
 */
mongoose.connection.on('error', function (err) {
    console.log('Mongoose connection error: ' + err);
});

/**
 * 連接斷開
 */
mongoose.connection.on('disconnected', function () {
    console.log('Mongoose connection disconnected');
});

module.exports = mongoose

4昌罩、使用

let User = require("../models/user");
var express = require('express');
var router = express.Router();
router.get('/add', async function (req, res, next) {
  var m = new User({
    uid: 'kkk',
    type: 2,
    uname: "飛牛",
    logintime: new Date
  });
  await m.save();
  res.send('add1');
})
module.exports = router;

在打開http://localhost:3000/users/add后,進(jìn)入studio 3T就看到添加了一條數(shù)據(jù)

image.png

七灾馒、自動(dòng)重啟工具nodemon

node程序在修改后茎用,都需要npm start重啟后才能生效,很麻煩睬罗。這里使用nodemon來實(shí)現(xiàn)自動(dòng)重啟轨功。
1、全局安裝

npm i -g nodemon

2容达、在項(xiàng)目根目錄新建nodemon.json

{
    "restartable": "rs",
    "ignore": [
        ".git",
        ".svn",
        "node_modules/**/node_modules"
    ],
    "verbose": true,
    "execMap": {
        "js": "node --harmony"
    },
    "watch": [
 
    ],
    "env": {
        "NODE_ENV": "development"
    },
    "ext": "js json"
}

restartable:設(shè)置重啟模式
ignore:設(shè)置忽略文件
verbose:設(shè)置日志輸出模式古涧,true 詳細(xì)模式
execMap:設(shè)置運(yùn)行服務(wù)的后綴名與對(duì)應(yīng)的命令
{ “js”: “node –harmony” }
表示使用 nodemon 代替 node
watch:監(jiān)聽哪些文件的變化,當(dāng)變化的時(shí)候自動(dòng)重啟
ext:監(jiān)控指定的后綴文件名
3花盐、啟動(dòng)
a羡滑、不使用express generator的項(xiàng)目菇爪,直接運(yùn)行nodemon app.js;
b、使用express generater的項(xiàng)目柒昏,在package.jsonscripts中添加"auto": "nodemon ./bin/www", 用npm run auto啟動(dòng)項(xiàng)目凳宙,源碼修改并保存之后,服務(wù)器就可以自動(dòng)啟動(dòng)了职祷。

八氏涩、設(shè)置session

1、安裝

npm install express-session --save

2有梆、app.js配置引入(務(wù)必放在路由配置前面)

var session = require('express-session');
//配置中間件
app.use(session({
  secret: "keyboard cat",
  resave: false,
  saveUninitialized: true,
  cookie: ('name', 'value', { maxAge: 5 * 60 * 1000, secure: false })
}));

3削葱、routes/users.js中使用

router.get('/login', async function (req, res, next) {
  req.session.username = "wjb";
  res.send('登錄成功!' + req.session.username);
})

router.get('/info', async function (req, res, next) {
  res.send('用戶信息:' + req.session.username);
})

router.get('/loginout', async function (req, res, next) {
  req.session.destroy(function (err) {
    res.send("退出登錄淳梦!" + err);
  });
})

頁面效果:


http://localhost:3000/users/login

http://localhost:3000/users/info

http://localhost:3000/users/loginout

http://localhost:3000/users/info

八、設(shè)置session(使用redis作為會(huì)話存儲(chǔ)實(shí)例)

1昔字、安裝

npm install redis connect-redis express-session

2爆袍、app.js配置引入

const redis = require('redis')
const session = require('express-session')
let RedisStore = require('connect-redis')(session)
let redisClient = redis.createClient()
//配置中間件
app.use(session({
  secret: "keyboard cat",
  resave: false,
  saveUninitialized: true,
  store: new RedisStore({ client: redisClient }),
  cookie: {
    secure: false,
    maxAge: 1000 * 60 * 60 * 24 * 30
  }
}));

3、routes/users.js中使用
使用方式同上沒有區(qū)別作郭。
執(zhí)行上面操作后陨囊,可以使用react redis查看redis數(shù)據(jù),如下圖:

使用react redis查看redis數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夹攒,一起剝皮案震驚了整個(gè)濱河市蜘醋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咏尝,老刑警劉巖压语,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異编检,居然都是意外死亡胎食,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門允懂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厕怜,“玉大人,你說我怎么就攤上這事蕾总≈嗪剑” “怎么了?”我有些...
    開封第一講書人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵生百,是天一觀的道長(zhǎng)递雀。 經(jīng)常有香客問我,道長(zhǎng)置侍,這世上最難降的妖魔是什么映之? 我笑而不...
    開封第一講書人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任拦焚,我火速辦了婚禮,結(jié)果婚禮上杠输,老公的妹妹穿的比我還像新娘赎败。我一直安慰自己,他們只是感情好蠢甲,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開白布僵刮。 她就那樣靜靜地躺著,像睡著了一般鹦牛。 火紅的嫁衣襯著肌膚如雪搞糕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,856評(píng)論 1 290
  • 那天曼追,我揣著相機(jī)與錄音窍仰,去河邊找鬼。 笑死礼殊,一個(gè)胖子當(dāng)著我的面吹牛驹吮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晶伦,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼碟狞,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了婚陪?” 一聲冷哼從身側(cè)響起族沃,我...
    開封第一講書人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泌参,沒想到半個(gè)月后脆淹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沽一,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年未辆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锯玛。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咐柜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出攘残,到底是詐尸還是另有隱情拙友,我是刑警寧澤,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布歼郭,位于F島的核電站遗契,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏病曾。R本人自食惡果不足惜牍蜂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一漾根、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鲫竞,春花似錦辐怕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至僵井,卻和暖如春陕截,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背批什。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工农曲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人驻债。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓朋蔫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親却汉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容