Node.js 学习笔记之五:使用 Express 框架
这部分示例将通过你好,Express
、留言板
和学生管理
三个应用的实现来演示Express
框架的基本使用。首先来搭建该示例项目的基本脚手架,为此我们需要在code
目录下执行mkdir 07_Expressjs
命令来创建用于存放这一组示例的目录,并执行一下步骤:
-
在
code/07_Expressjs
目录下执行npm init --yes
命令来初始化本示例项目。 -
在
code/07_Expressjs
目录下执行npm install express body-parser sqlite3 mongodb async art-template express-art-template --save
命令来安装本示例所要用到的扩展包。 -
在
code/07_Expressjs
目录下执行mkdir views
命令来创建用于存放模板文件的目录。 -
在
code/07_Expressjs
目录下执行mkdir public
命令创建public
目录,并进入到该目录中,执行mkdir DB css js img
命令来创建用于存放相应类型资源的目录。 -
在
code/07_Expressjs
目录下执行touch index.js
命令,创建本示例的程序入口文件,具体代码如下:const path = require('path') const express = require('express') const bodyParser =require('body-parser') const router = require(path.join(__dirname, 'router')) const app = express() // 配置public目录 app.use('/public/', express.static(path.join(__dirname, 'public'))) //配置body-parser中间件`,以便获取post请求数据。` app.use(bodyParser.urlencoded({extended : false})); app.use(bodyParser.json()); // 配置模板引擎为art-template app.engine('htm', require('express-art-template')) app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'art') // 调用路由表函数 app.(router) // 监听8080端口 app.listen(8080, function(){ console.log('请访问http://localhost:8080/,按Ctrl+C终止服务!') })
-
在
code/07_Expressjs
目录下执行touch router.js
命令,创建本示例的程序路由文件,具体代码如下:const path = require('path') const express = require('express') const sayHello = require(path.join(__dirname, 'sayHello')) const student = require(path.join(__dirname, 'student')) const board = require(path.join(__dirname, 'board')) const router = express.Router() // Hello,Express! sayHello(router) // 学生管理 student(router) // 留言板 board(router) module.exports = router
-
在
code/07_Expressjs
目录下执行touch baseTpl.js
命令,创建该项目的基础模版文件,并在其中输入以下代码:<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <!-- Bootstrap CSS --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- 自定义 CSS --> <link href="/public/css/main.css" rel="stylesheet"> <title>Express使用示例</title> </head> <body> <div class="container"> <!-- 导航栏部分开始 --> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">切换导航栏</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Express使用示例</a> </div> {{ block 'navbar' }} {{ /block }} </div> </nav> <!-- 导航栏部分结束 --> <!-- 主体部分开始 --> {{ block 'main' }} {{ /block }} <!-- 主体部分结束 --> </div> <!-- Bootstrap的核心JavaScript ================================================== --> <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script> <script> window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> </body> </html>
-
在
code/07_Expressjs/public/css/
目录创建一个名为main.css
的样式文件,内容如下:body { padding-top: 10px; }
下面,我们要在这个脚手架上逐一来创建之前所说的三个应用示例。
1. 你好,Express
这个应用示例主要用于示范如何用Express
框架来创建一个 Web 页面,并使用art-template
模板引擎。其主要步骤如下:
-
在
code/07_Expressjs/public/img/
目录下放置一张Express
官网首页的截图,将其命名为express.jpeg
。 -
在
code/07_Expressjs/views/
目录创建一个名为hello.htm
的模版文件,内容如下:{{ extend './baseTpl.art' }} {{ block 'navbar' }} <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="/">你好,Express!</a></li> <li><a href="/student">学生管理</a></li> <li><a href="/board">留言板</a></li> </ul> </div> {{ /block }} {{ block 'main' }} <div class="jumbotron"> <h1>你好,{{ name }}!</h1> <img src="/public/img/express.jpeg" class="img-responsive"> </div> {{ /block }}
-
在
code/07_Expressjs
目录下执行mkdir sayHello
命令来创建该应用的目录,并在其中创建一个名为index.js
的脚本文件,内容如下:module.exports = function(app) { app.get('/', function (req, res) { res.render('hello.htm', {name : 'Express'}) }) }
-
保存所有文件后,在
code/07_Expressjs
目录下执行node index.js
命令,结果如下:
2. 学生管理
这个应用示例主要用于演示如何用Express
框架实现学生管理系统,并使用SQLite3
作为数据库,其具体步骤如下:
-
在
code/07_Expressjs/views/
目录创建一个名为student.htm
的模版文件,内容如下:{{ extend './baseTpl.art' }} {{ block 'navbar' }} <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/">你好,Express!</a></li> <li class="active"><a href="/student">学生管理</a></li> <li><a href="/board">留言板</a></li> </ul> </div> {{ /block }} {{ block 'main' }} <div class="jumbotron"> <h2>学生信息表</h2> <a class="btn btn-success" href="/student/add">添加学生</a> <table class="table table-striped"> <tr> <th>姓名</th> <th>年龄</th> <th>性别</th> <th>爱好</th> <th>操作</th> </tr> {{ each db }} <tr> <td>{{ $value.name }} </td> <td>{{ $value.age }} </td> <td>{{ $value.sex }} </td> <td>{{ $value.items }}</td> <td> <a href="/student/edit?name={{ $value.name}}">编辑</a> <a href="/student/delete?name={{ $value.name}}">删除</a> </td> </tr> {{ /each }} </table> </div> {{ /block }}
-
在
code/07_Expressjs/views/
目录创建一个名为add.htm
的模版文件,内容如下:{{ extend './baseTpl.art' }} {{ block 'navbar' }} <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/">你好,Express!</a></li> <li class="active"><a href="/student">学生管理</a></li> <li><a href="/board">留言板</a></li> </ul> </div> {{ /block }} {{ block 'main' }} <div class="jumbotron"> <h2>注册新学生:</h2> <form action="/student/add" method="POST" class="form-horizontal" role="form"> <div class="form-group"> <label for="firstname" class="col-sm-2 control-label">姓名:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" placeholder="请输入名字"> </div> </div> <div class="form-group"> <label for="lastname" class="col-sm-2 control-label">年龄:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="age" placeholder="请输入年龄"> </div> </div> <div class="form-group"> <label for="lastname" class="col-sm-2 control-label">性别:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="sex" placeholder="请输入性别"> </div> </div> <div class="form-group"> <label for="lastname" class="col-sm-2 control-label">爱好:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="items" placeholder="请输入爱好"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">加入</button> </div> </div> </form> </div> {{ /block }}
-
在
code/07_Expressjs/views/
目录创建一个名为edit.htm
的模版文件,内容如下:{{ extend './baseTpl.art' }} {{ block 'navbar' }} <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/">你好,Express!</a></li> <li class="active"><a href="/student">学生管理</a></li> <li><a href="/board">留言板</a></li> </ul> </div> {{ /block }} {{ block 'main' }} <div class="jumbotron"> <h2>编辑 {{ name }} 的信息:</h2> <form action="/student/edit" method="POST" class="form-horizontal" role="form"> <div class="form-group"> <label for="firstname" class="col-sm-2 control-label">姓名:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" value="{{ name }}" placeholder="请输入名字"> </div> </div> <div class="form-group"> <label for="lastname" class="col-sm-2 control-label">年龄:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="age" value="{{ age }}" placeholder="请输入年龄"> </div> </div> <div class="form-group"> <label for="lastname" class="col-sm-2 control-label">性别:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="sex" value="{{ sex }}" placeholder="请输入性别"> </div> </div> <div class="form-group"> <label for="lastname" class="col-sm-2 control-label">爱好:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="items" value="{{ items }}" placeholder="请输入爱好"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">更新数据</button> </div> </div> </form> </div> {{ /block }}
-
在
code/07_Expressjs
目录下执行mkdir student
命令来创建该应用的目录,并在其中创建一个名为index.js
和Sqlite.js
的两个脚本文件,内容如下:- index.js
const fs = require('fs') const path = require('path') const async = require('async') const SqliteDB = require(path.join(__dirname,'Sqlite')) const dbPath = path.join(__dirname, '../public/DB/studentsDB.db') // 配置数据库 if ( !fs.existsSync(dbPath) ) { const studentsDB = new SqliteDB(dbPath) async.series([ function(callback) { const createTableSql = ` create table if not exists STUDENT_TABLE ( name TEXT, age TEXT, sex TEXT, items TEXT )` studentsDB.createTable(createTableSql) callback() }, function(callback) { const insertTileSql = ` insert into STUDENT_TABLE (name, age, sex, items) values(?, ?, ?, ?)` const arr = [ ['凌杰', '24', '男', '看书、看电影、旅游'], ['蔓儿', '25', '女', '看书、看电影、写作'], ['张语', '32', '女', '看书、旅游、绘画'] ] studentsDB.insertData(insertTileSql, arr) callback() } ]) studentsDB.close() } module.exports = function(app) { app.get('/student', function (req, res) { const studentsDB = new SqliteDB(dbPath) const querySql = 'select * from STUDENT_TABLE' studentsDB.queryData(querySql, function(data) { if ( data === null ) { return console.log('数据查询错误!') } res.render('student.htm', { db : data }) }) studentsDB.close() }) app.get('/student/add', function (req, res) { res.render('add.htm', { }) }) app.post('/student/add', function (req, res) { const studentsDB = new SqliteDB(dbPath) const arr = [ [req.body['name'],req.body['age'],req.body['sex'],req.body['items']] ] const insertTileSql = ` insert into STUDENT_TABLE (name, age, sex, items) values(?, ?, ?, ?)` studentsDB.insertData(insertTileSql, arr) studentsDB.close() res.redirect('/student') }) app.get('/student/delete', function (req, res) { const studentsDB = new SqliteDB(dbPath) const deleteSql = ` delete from STUDENT_TABLE where name = '` + req.query['name'] + `'` studentsDB.executeSql(deleteSql) studentsDB.close() res.redirect('/student') }) app.get('/student/edit', function (req, res) { const studentsDB = new SqliteDB(dbPath) const querySql = ` select * from STUDENT_TABLE where name = '` + req.query['name'] + `'` studentsDB.queryData(querySql, function(data) { if ( data === null ) { return console.log('数据查询错误!') } res.render('edit.htm', { name : data[0]['name'], age : data[0]['age'], sex : data[0]['sex'], items : data[0]['items'] }) }) studentsDB.close() }) app.post('/student/edit', function (req, res) { const studentsDB = new SqliteDB(dbPath) const updateSql = `update STUDENT_TABLE set name = '` + req.body['name'] + `', ` + `age = '` + req.body['age'] + `', ` + `sex = '` + req.body['sex'] + `', ` + `items = '` + req.body['items'] + `' ` + ` where name = '` + req.body['name'] + `'` studentsDB.executeSql(updateSql) studentsDB.close() res.redirect('/student') }) }
- Sqlite.js
const fs = require('fs') const sqlite3 = require('sqlite3').verbose() class SqliteDB { constructor(file) { this.db = new sqlite3.Database(file) const db_exist = fs.existsSync(file) if ( !db_exist ) { fs.openSync(file, 'w') } } createTable(sql) { this.db.serialize(function() { this.run(sql, function(err) { if( err !== null ) { return console.error('错误信息:' + err.message) } }) }) } insertData(sql, objects) { this.db.serialize(function() { const stmt = this.prepare(sql) for ( const i = 0; i < objects.length; ++i ) { stmt.run(objects[i]) } stmt.finalize() }) } queryData(sql, callback) { this.db.all(sql, function(err, rows) { if( err !== null ) { return console.error('错误信息:' + err.message) } if( callback ) { callback(rows) } }) } executeSql(sql) { this.db.run(sql, function(err) { if( err !== null ) { return console.error('错误信息:' + err.message) } }) } close() { this.db.close() } } module.exports = SqliteDB
-
保存所有文件后,在
code/07_Expressjs
目录下执行node index.js
命令,结果如下:
3. 留言板
这个应用示例主要用于演示如何用Express
框架实现留言板应用,并使用MongoDB
作为数据库,其具体步骤如下:
-
在
code/07_Expressjs/views/
目录创建一个名为board.htm
的模版文件,内容如下:{{ extend './baseTpl.art' }} {{ block 'navbar' }} <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/">你好,Express!</a></li> <li><a href="/student">学生管理</a></li> <li class="active"><a href="/board">留言板</a></li> </ul> </div> {{ /block }} {{ block 'main' }} <div class="jumbotron"> <h2>留言板</h2> <form action="/board" method="POST" class="form-horizontal" role="form"> <div class="form-group"> <label for="firstname" class="col-sm-2 control-label">你的姓名:</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" placeholder="请输入名字"> </div> </div> <div class="form-group"> <label for="lastname" class="col-sm-2 control-label">留言信息:</label> <div class="col-sm-10"> <textarea class="form-control" name="message" placeholder="请输入留言"></textarea> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交留言</button> </div> </div> </form> </div> <div class="jumbotron"> <h3>最新留言({{ num }} 则):</h3> <table class="table"> {{ each db }} <tr> <td>{{ $value.name }} </td> <td>{{ $value.message }} </td> <td>{{ $value.time }}</td> </tr> {{ /each }} </table> </div> {{ /block }}
-
在
code/07_Expressjs
目录下执行mkdir board
命令来创建该应用的目录,并在其中创建一个名为index.js
的脚本文件,内容如下:const MongoClient = require('mongodb').MongoClient const async = require('async') const server = 'mongodb://localhost:27017' const dbName = 'boardDB' const collName = 'message_table' const dbPath = server + '/' + dbName module.exports = function(app) { app.get('/board', function (req, res) { MongoClient.connect(dbPath, { useNewUrlParser: true }, function(err, db) { if ( err !== null ) { return console.error('错误信息:' + err.message) } const dbo = db.db(dbName) const collect = dbo.collection(collName) collect. find({}).toArray(function(err, result) { if ( err !== null ) { return console.error('错误信息:' + err.message) } const num =result.length res.render('board.htm', { num : num, db : result }) }) }) }) app.post('/board', function (req, res) { MongoClient.connect(dbPath, { useNewUrlParser: true }, function(err, db) { if ( err !== null ) { return console.error('错误信息:' + err.message) } const dbo = db.db(dbName) const collect = dbo.collection(collName) const data = { name : req.body['name'], message : req.body['message'], time : Date() } collect.insertOne(data, function(err, res) { if ( err !== null ) { return console.error('错误信息:' + err.message) } }) res.redirect('/board') }) }) }
-
保存所有文件后,在
code/07_Expressjs
目录下执行node index.js
命令,结果如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?