NodeJS七天课程学习笔记_第4天
课程内容概要:
1.Nodemon 自重启
2.Express 静态资源路由的4种情况
3.使用Express框架重写 node_21.js 留言本demo
关于/的几个注意事项
1. 文件读取时, 读readFile当前目录下的文件时,
可以写’./anohana.txt’, 也可以省略”./”
所有的文件操作,都是异步操作
如果,只是省略了前面的点, 以斜杠开头的话,比如”/bin/anohana.txt”
所代表的是,从磁盘的根目录下的bin文件夹下的anohana.txt读取
2. require加载当前路径下的自定义模块时, “./”不能省略
如果省略点, 以斜杠开头的话,也是代表从磁盘根目录下开始查找模块
NodeJS七天课程主讲老师:李鹏周
第3方命令行工具 nodemon 解决重启问题
第1步: 安装nodemon,在任意目录下执行以下命令:
sudo npm install –global nodemon
第2步: 运行的时候,不再使用 node xxx.js ,
而是使用 nodemon xxx.js 即可
nodemon的原理: 只要是使用nodemon 启动的服务,它会监视文件的改动,自动重启
nodemon的演示效果如下:
Express 静态资源访问的4种情况
事先说明:
在网站的根目录下,有一个public文件夹,里面又有js、css、img、lib等文件夹
例如: /public/img/beyond.jpg
第1种情况:照原样访问
例如请求方式使用: http://localhost:5267/public/img/beyond.jpg
代码如下:
var urlPrefix = '/public/'
或者
var urlPrefix = '/public'
// 当前目录下的public文件夹
var filePath = './public/' // 也可以直接 'public'
var callbackFunction = expressExport.static(filePath)
appServer.use(urlPrefix,callbackFunction)
完整代码如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 导入框架
var expressExport = require('express')
// 创建服务器对象
var appServer = expressExport()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// 处理get请求
appServer.get('/',function (request,response) {
// 至于请求参数可以这样:
var queryObj = request.query
response.send('<html><head><title>beyond心中の动漫神作</title><link rel="icon" href="/public/img/beyond.jpg" /></head><body style="background-image:url(/public/img/sakura4.png);background-repeat:no-repeat;background-position:center center;"><h1 style="text-align:center;color:white;text-shadow:2px 2px 4px #001;letter-spacing:5px;">未闻花名</h1></body></html>')
})
// url不做任何变化 ,照原样访问
// localhost:5267/public/img/beyond.jpg
var urlPrefix = '/public/'
// var urlPrefix = '/public' 这样写也可以
// 静态资源在磁盘上的目录
var filePath = './public/' // 也可以直接 'public'
var callbackFunction = expressExport.static(filePath)
NSLog('callbackFunction: + \n' + typeof(callbackFunction))
appServer.use(urlPrefix,callbackFunction)
效果如下:
第2种情况:起别名
请求方式url中也要使用别名: http://localhost:5267/static/img/beyond.jpg
代码如下:
var urlPrefix = '/static/'
或者
var urlPrefix = '/static'
// 当前目录下的public文件夹
var filePath = './public/' // 也可以直接 'public'
var callbackFunction = expressExport.static(filePath)
appServer.use(urlPrefix,callbackFunction)
完整代码如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 导入框架
var expressExport = require('express')
// 创建服务器对象
var appServer = expressExport()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// 处理get请求
appServer.get('/',function (request,response) {
// 至于请求参数可以这样:
var queryObj = request.query
response.send('<html><head><title>beyond心中の动漫神作</title><link rel="icon" href="/static/img/beyond.jpg" /></head><body style="background-image:url(/static/img/sakura4.png);background-repeat:no-repeat;background-position:center center;"><h1 style="text-align:center;color:white;text-shadow:2px 2px 4px #001;letter-spacing:5px;">未闻花名</h1></body></html>')
})
// 给url起个别名
// 访问也只能使用 localhost:5267/static/img/beyond.jpg
// var urlPrefix = '/static/'
var urlPrefix = '/static' // 这样写也可以
// 磁盘上的静态资源目录
var filePath = './public/' // 也可以直接 'public'
var callbackFunction = expressExport.static(filePath)
NSLog('callbackFunction: + \n' + typeof(callbackFunction))
appServer.use(urlPrefix,callbackFunction)
效果如下:
第3种情况:简化(省略)url路径
在url请求中,也使用简化(省略)后的url路径: http://localhost:5267/img/beyond.jpg
// 没有urlPrefix了
// 当前目录下的public文件夹
var filePath = './public/' // 也可以直接 'public'
var callbackFunction = expressExport.static(filePath)
appServer.use(callbackFunction)
完整代码如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 导入框架
var expressExport = require('express')
// 创建服务器对象
var appServer = expressExport()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// 处理get请求
appServer.get('/',function (request,response) {
// 至于请求参数可以这样:
var queryObj = request.query
response.send('<html><head><title>beyond心中の动漫神作</title><link rel="icon" href="/img/beyond.jpg" /></head><body style="background-image:url(/img/sakura4.png);background-repeat:no-repeat;background-position:center center;"><h1 style="text-align:center;color:white;text-shadow:2px 2px 4px #001;letter-spacing:5px;">未闻花名</h1></body></html>')
})
// 没有 urlPrefix 了
// 访问也只能使用 localhost:5267/img/beyond.jpg
// 磁盘上的静态资源目录
var filePath = './public/' // 也可以直接 'public'
var callbackFunction = expressExport.static(filePath)
NSLog('callbackFunction: + \n' + typeof(callbackFunction))
appServer.use(callbackFunction)
效果如下:
第4种情况:下次再讲
在Express中使用art-template模板引擎
注意: 在art-template官方网站上有详细介绍在express/koa中如何使用模板引擎
第1步安装:
npm install art-template –save
npm install express-art-template –save
运行结果如下:
第2步配置:
核心代码就一句:
appServer.engine(‘html‘,require(‘express-art-template‘))
解释一下:
对于(views目录下)所有后缀名为html的文件,使用模板引擎
注意:如果 不想把模板文件放在默认的views目录下 ,则可以通过下面代码更改设置
appServer.set(‘views’,’其他目录’)
第3步使用:
appServer.get(‘/’,function(request,response){
response.render(‘index/index.html‘,{
girlName: ‘mathilda’,
girlAge: 12,
girlLikeArr: [‘leon’,’milk’,’imitation show’]
})
})
解释说明一下:
模板位置是在网站的根目录下 views目录中 index文件夹里的 index.html
静态资源是在网站的根目录下 public目录中 img 和 js 和 css 文佳夹里
node_27_3.js 完整使用示例如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 导入框架
var express = require('express')
// 创建服务器对象
var appServer = express()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// 指明:对于 所有后缀为html 的模板文件 使用模板引擎
var templateFileSuffix = 'html'
appServer.engine(templateFileSuffix,require('express-art-template'))
// 下面这一句参数配置,可有可无
appServer.set('view options',{
debug: process.env.NODE_ENV !== 'production'
})
// 注意:如果不想把模板文件放在默认的views目录下,则可以通过下面代码更改设置
// appServer.set('views','其他目录')
// 处理get请求
appServer.get('/',function (request,response) {
// 至于请求参数可以这样:
var queryObj = request.query
// 使用模板引擎渲染
// 注意: 模板文件默认是放在views目录下
// 为此,我们在views目录下 分别为不同的业务模块创建了不同的文件夹
// 如 login登录 admin后台管理 index前台首页 article文章 comment评论
response.render('index/node_27_3_template.html',{
author: 'beyond',
girlName: 'mathilda',
girlAge: 12,
loveArr:['leon','milk','imitation show']
})
})
// 静态资源请求时的 staticFileUrlPrefix
var staticFileUrlPrefix = '/public/'
// var staticFileUrlPrefix = '/public'
// 访问也只能使用 localhost:5267/public/img/beyond.jpg
// 磁盘上的静态资源目录
var staticFilePath = './public/'
// var staticFilePath = 'public'
var callbackFunction = express.static(staticFilePath)
appServer.use(staticFileUrlPrefix,callbackFunction)
views目录下index文件夹里的模板文件node_27_3_template.html完整内容如下:
<!DOCTPYE html>
<html lang="zh">
<head>
<link rel="icon" href="/public/img/beyond2.jpg" type="image/x-icon"/>
<meta charset="UTF-8">
<meta name="author" content="beyond">
<meta http-equiv="refresh" content="520">
<meta name="description" content="未闻花名-免费零基础教程-beyond">
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
<meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY,XML,JSON,C,C++,C#,OC,PHP,JAVA,JSP,PYTHON,RUBY,PERL,LUA,SQL,LINUX,SHELL,汇编,日语,英语,泰语,韩语,俄语,粤语,阿语,魔方,乐理,动漫,PR,PS,AI,AE">
<title>beyond心中の动漫神作</title>
<link rel="stylesheet" type="text/css" href="/public/css/beyondbasestylewhite5.css">
<style type="text/css">
body{
font-size: 100%;
/*声明margin和padding是个好习惯*/
margin: 0;
padding: 0;
padding-left: 10px;
padding-right: 10px;
background-image: url("/public/img/sakura4.png");
background-repeat: no-repeat;
background-position: center center;
}
</style>
<!-- 绿色按钮的css效果 -->
<link rel="stylesheet" type="text/css" href="/public/css/beyondbuttongreen.css">
</head>
<body>
<h1 style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">
未闻花名
</h1>
<div style="margin:0 auto;text-align:center">
hi {{ author }} <br/>
it's {{ girlName }},I'm {{ girlAge }} years old,I like :</br>
{{ each loveArr }}
{{ $index }} : {{ $value }} <br/>
{{ /each }}
</div>
<footer id="copyright">
<p style="font-size:14px;text-align:center;font-style:italic;">
Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>
</p>
</footer>
</body>
</html>
在命令行中,使用 命令: nodemon node_27_3.js 运行效果如下:
浏览器访问: localhost:5267 效果如下:
将前面的node_21.js实现的留言板demo,通过express框架重写一下
node_28.js代码如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 导入框架
var express = require('express')
// 创建服务器对象
var appServer = express()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// -----------------------------------
// 静态资源请求时的 staticFileUrlPrefix
var staticFileUrlPrefix = '/public/'
// var staticFileUrlPrefix = '/public'
// 访问也只能使用 localhost:5267/public/img/beyond.jpg
// 磁盘上的静态资源目录
var staticFilePath = './public/'
// var staticFilePath = 'public'
var callbackFunction = express.static(staticFilePath)
appServer.use(staticFileUrlPrefix,callbackFunction)
// -----------------------------------
// 指明:对于 所有后缀为html 的模板文件 使用模板引擎
var templateFileSuffix = 'html'
appServer.engine(templateFileSuffix,require('express-art-template'))
// 下面这一句参数配置,可有可无
appServer.set('view options',{
debug: process.env.NODE_ENV !== 'production'
})
// 注意:如果不想把模板文件放在默认的views目录下,则可以通过下面代码更改设置
// appServer.set('views','其他目录')
// -----------------------------------
var dataObject = {
recordArr:[
{
girlName: '面码',
girlDescription: '未闻花名',
pubTime: '2006-06-07'
},
{
girlName: 'mathilda',
girlDescription: '这个杀手不太冷',
pubTime: '2006-06-07'
}
]
}
// -----------------------------------
// 处理get请求
appServer.get('/',function (request,response) {
// 至于请求参数可以这样:
var queryObj = request.query
// 使用模板引擎渲染
// 注意: 模板文件默认是放在views目录下
// 为此,我们在views目录下 分别为不同的业务模块创建了不同的文件夹
// 如 login登录 admin后台管理 index前台首页 article文章 comment评论
response.render('index/node_28_index.html',dataObject)
})
// 处理get请求
appServer.get('/write',function (request,response) {
// 没有数据需要绑定的时候,不传第2个参数即可
response.render('index/node_28_write.html')
})
// 处理get请求
appServer.get('/insert',function (request,response) {
// 至于请求参数可以这样:
var queryObj = request.query
queryObj.pubTime = '2018-06-07'
// 提交评论,理论上应该插入数据库,然后重新刷新
// 这儿只是临时加到数组的最前面
dataObject.recordArr.unshift(queryObj)
// 临时重定向
response.redirect('/')
})
效果如下:
下面再将留言板demo由get请求改成post请求
在express中,获取get请求中的参数对象,只需要
var queryObject = request.query 即可
在express中,获取post请求中的参数对象,需要两个步骤
第1步: 安装 body-parser 这个 中间件middleware (可在express官网上resource菜单中看到)
express官网中的middleware列表地址如下:http://expressjs.com/en/resources/middleware.html
安装命令: npm install body-parser –save
第2步: 配置 3 行代码
var bodyParser = require('body-parser')
// 设置解析 application/x-www-form-urlencoded
appServer.use(bodyParser.urlencoded({extended: false}))
// 设置解析 application/json
appServer.use(bodyParser.json())
第3步: 使用 body-parser 解析出post提交过来的对象
var postObj = request.body
下面演示 将留言板demo由get请求改成post请求
第1步:
先将views目录下的index文件夹下的html模板文件:
node_29_insert.html中 表单的method属性 由get改成post
第2步:
在node_29.js中,引入body-parser,并进行配置,最后再处理post请求
node_29.js完整代码如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 导入框架
var express = require('express')
// 创建服务器对象
var appServer = express()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// -----------------------------------
// 静态资源请求时的 staticFileUrlPrefix
var staticFileUrlPrefix = '/public/'
// var staticFileUrlPrefix = '/public'
// 访问也只能使用 localhost:5267/public/img/beyond.jpg
// 磁盘上的静态资源目录
var staticFilePath = './public/'
// var staticFilePath = 'public'
var callbackFunction = express.static(staticFilePath)
appServer.use(staticFileUrlPrefix,callbackFunction)
// -----------------------------------
// 指明:对于 所有后缀为html 的模板文件 使用模板引擎
var templateFileSuffix = 'html'
appServer.engine(templateFileSuffix,require('express-art-template'))
// 下面这一句参数配置,可有可无
appServer.set('view options',{
debug: process.env.NODE_ENV !== 'production'
})
// 注意:如果不想把模板文件放在默认的views目录下,则可以通过下面代码更改设置
// appServer.set('views','其他目录')
// -----------------------------------
var dataObject = {
recordArr:[
{
girlName: '面码',
girlDescription: '未闻花名',
pubTime: '2006-06-07'
},
{
girlName: 'mathilda',
girlDescription: '这个杀手不太冷',
pubTime: '2006-06-07'
}
]
}
// -----------------------------------
// 处理get请求
appServer.get('/',function (request,response) {
// 至于请求参数可以这样:
var queryObj = request.query
// 使用模板引擎渲染
// 注意: 模板文件默认是放在views目录下
// 为此,我们在views目录下 分别为不同的业务模块创建了不同的文件夹
// 如 login登录 admin后台管理 index前台首页 article文章 comment评论
response.render('index/node_29_index.html',dataObject)
})
// 处理get请求
appServer.get('/write',function (request,response) {
// 没有数据需要绑定的时候,不传第2个参数即可
response.render('index/node_29_write.html')
})
// // 处理get请求
// appServer.get('/insert',function (request,response) {
// // 至于请求参数可以这样:
// var queryObj = request.query
// queryObj.pubTime = '2018-06-07'
// // 提交评论,理论上应该插入数据库,然后重新刷新
// // 这儿只是临时加到数组的最前面
// dataObject.recordArr.unshift(queryObj)
// // 临时重定向
// response.redirect('/')
// })
// -----------------------------------
// 使用middleware中间件body-parser进行post请求体中数据解析
var bodyParser = require('body-parser')
// 设置解析 application/x-www-form-urlencoded
appServer.use(bodyParser.urlencoded({extended: false}))
// 设置解析 application/json
appServer.use(bodyParser.json())
// 处理post请求
appServer.post('/insert',function (request,response) {
// 至于请求参数可以这样:
var postObject = request.body
postObject.pubTime = '2018-06-07'
// 提交评论,理论上应该插入数据库,然后重新刷新
// 这儿只是临时加到数组的最前面
dataObject.recordArr.unshift(postObject)
// 临时重定向
response.redirect('/')
})
执行效果如下:
青花瓷Charles抓包如下:
下面的node_30.js 做一个CRUD的小demo
首页模板node_30_index.html 是从bootstrap的后台模板中,
通过右键查看源代码,扒下来的:https://v3.bootcss.com/examples/dashboard/
node_30_index.html内容如下:
<!DOCTPYE html>
<html lang="zh">
<head>
<link rel="icon" href="/public/img/beyond2.jpg" type="image/x-icon"/>
<meta charset="UTF-8">
<meta name="author" content="beyond">
<meta http-equiv="refresh" content="520">
<meta name="description" content="未闻花名-免费零基础教程-beyond">
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
<meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY,XML,JSON,C,C++,C#,OC,PHP,JAVA,JSP,PYTHON,RUBY,PERL,LUA,SQL,LINUX,SHELL,汇编,日语,英语,泰语,韩语,俄语,粤语,阿语,魔方,乐理,动漫,PR,PS,AI,AE">
<title>beyond心中の动漫神作</title>
<link rel="stylesheet" type="text/css" href="/public/css/beyondbasestylewhite5.css">
<script type="text/javascript" src="/public/js/nslog.js"></script>
<!--[if lt IE 9]>
<script src="//apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">
</script>
<![endif]-->
<style type="text/css">
body{
font-size: 100%;
/*声明margin和padding是个好习惯*/
margin: 0;
padding: 0;
background-image: url("/public/img/sakura4.png");
background-repeat: no-repeat;
background-position: center center;
}
</style>
<!-- 绿色按钮的css效果 -->
<link rel="stylesheet" type="text/css" href="/public/css/beyondbuttongreen.css">
<!-- 引入 jquery 2.1.4 -->
<!--[if gte IE 9]><!-->
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js">
</script>
<!--<![endif]-->
<link rel="stylesheet" type="text/css" href="/public/lib/bootstrap/bootstrap.css">
<!-- 分隔线 -->
<!-- Bootstrap core CSS -->
<link href="/public/lib/node30_337_bootstrap.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="/public/css/node30dashboard.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<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">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#" style="color:white;">beyond</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Dashboard</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Help</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search...">
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
<li><a href="">More navigation</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header" style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">未闻花名</h1>
<div class="row placeholders">
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
</div>
<h2 class="sub-header">动漫神作列表</h2>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>id</th>
<th>芳名</th>
<th>年龄</th>
<th>动漫</th>
<th>日期</th>
</tr>
</thead>
<tbody>
{{ each recordArr }}
<tr>
<td>{{ $value.girlID }}</td>
<td>{{ $value.girlName }}</td>
<td>{{ $value.girlAge }}</td>
<td>{{ $value.girlDescription }}</td>
<td>{{ $value.pubTime }}</td>
</tr>
{{ /each }}
</tbody>
</table>
</div>
</div>
</div>
</div>
<footer id="copyright">
<p style="font-size:14px;text-align:center;font-style:italic;">
Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>
</p>
</footer>
</body>
</html>
node_30.js代码如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 使用文件数据库
var fs = require('fs')
// 导入框架
var express = require('express')
// 创建服务器对象
var appServer = express()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// -----------------------------------
// 静态资源请求时的 staticFileUrlPrefix
var staticFileUrlPrefix = '/public/'
// var staticFileUrlPrefix = '/public'
// 访问也只能使用 localhost:5267/public/img/beyond.jpg
// 磁盘上的静态资源目录
var staticFilePath = './public/'
// var staticFilePath = 'public'
var callbackFunction = express.static(staticFilePath)
appServer.use(staticFileUrlPrefix,callbackFunction)
// -----------------------------------
// 指明:对于 所有后缀为html 的模板文件 使用模板引擎
var templateFileSuffix = 'html'
appServer.engine(templateFileSuffix,require('express-art-template'))
// 下面这一句参数配置,可有可无
appServer.set('view options',{
debug: process.env.NODE_ENV !== 'production'
})
// 注意:如果不想把模板文件放在默认的views目录下,则可以通过下面代码更改设置
// appServer.set('views','其他目录')
// -----------------------------------
// 处理get请求
appServer.get('/',function (request,response) {
// 至于请求参数可以这样:
// var queryObj = request.query
// 第2个参数: 可以指定读取的编码
fs.readFile('node_30.db','utf8',function (error,data) {
if (error) {
return response.status(500).send('服务器内部错误')
}
// 将读取字符串,转成对象
var dataObject = JSON.parse(data)
// 使用模板引擎渲染
// 注意: 模板文件默认是放在views目录下
// 为此,我们在views目录下 分别为不同的业务模块创建了不同的文件夹
// 如 login登录 admin后台管理 index前台首页 article文章 comment评论
response.render('index/node_30_index.html',dataObject)
})
})
// 处理get请求
appServer.get('/write',function (request,response) {
// 没有数据需要绑定的时候,不传第2个参数即可
response.render('index/node_29_write.html')
})
数据库node_30.db文件如下:
{
"recordArr" : [
{
"girlID": 1,
"girlName": "面码",
"girlAge": 15,
"girlDescription": "未闻花名",
"pubTime": "2006-06-07"
},
{
"girlID": 2,
"girlName": "逢坂大河",
"girlAge": 16,
"girlDescription": "龙与虎",
"pubTime": "2007-06-07"
},
{
"girlID": 3,
"girlName": "k-on",
"girlAge": 12,
"girlDescription": "轻音少女",
"pubTime": "2008-06-07"
},
{
"girlID": 4,
"girlName": "mathilda",
"girlAge": 12,
"girlDescription": "这个杀手不太冷",
"pubTime": "2009-06-07"
}
]
}
效果如下:
推荐了一本书: <结构思维>
从Node开始,后面还会遇到相当多的第3方的,如vue,angular,react,webpack
优先以解决问题为主, 有精力的话再去探求原理
下面演示的是 如何在express中,使用自定义路由模块
自定义路由设计的目的是:
1.让主入口程序的职责更加单一,代码更加简洁
1.1 创建服务
1.2 做一些服务相关的配置,比如:
1.2.1 静态资源配置
1.2.2 模板引擎配置
1.2.3 body-parse 解析表单
1.2.4 挂载自定义路由
1.2.5 监听端口,启动服务
注意: 在主程序app中,配置模板引擎和body-parser, 一定要在挂载路由之前
node_31.js_router.js代码如下:
// express 专门提供了路由的处理方法
var express = require('express')
// 1.使用express专门提供的路由器处理路由
var router = express.Router()
var fs = require('fs')
router.get('/',function (request,response) {
// 至于请求参数可以这样:
// var queryObj = request.query
// 第2个参数: 可以指定读取的编码
fs.readFile('node_31.db','utf8',function (error,data) {
if (error) {
return response.status(500).send('服务器内部错误')
}
// 将读取字符串,转成对象
var dataObject = JSON.parse(data)
// 使用模板引擎渲染
// 注意: 模板文件默认是放在views目录下
// 为此,我们在views目录下 分别为不同的业务模块创建了不同的文件夹
// 如 login登录 admin后台管理 index前台首页 article文章 comment评论
response.render('index/node_31_index.html',dataObject)
})
})
// 3.在模块文件最后,导出router
module.exports = router主
使用了自定义路由模块的主程序入口文件node_31.js如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 导入框架
var express = require('express')
// 创建服务器对象
var appServer = express()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// -----------------------------------
// 静态资源请求时的 staticFileUrlPrefix
var staticFileUrlPrefix = '/public/'
// var staticFileUrlPrefix = '/public'
// 访问也只能使用 localhost:5267/public/img/beyond.jpg
// 磁盘上的静态资源目录
var staticFilePath = './public/'
// var staticFilePath = 'public'
var callbackFunction = express.static(staticFilePath)
appServer.use(staticFileUrlPrefix,callbackFunction)
// -----------------------------------
// 指明:对于 所有后缀为html 的模板文件 使用模板引擎
var templateFileSuffix = 'html'
appServer.engine(templateFileSuffix,require('express-art-template'))
// 下面这一句参数配置,可有可无
appServer.set('view options',{
debug: process.env.NODE_ENV !== 'production'
})
// 注意:如果不想把模板文件放在默认的views目录下,则可以通过下面代码更改设置
// appServer.set('views','其他目录')
// -------------注意: 配置模板引擎和body-parser, 一定要在挂载路由之前
// 使用自定义的路由模块 必须使用./
var beyondRouter = require('./node_31_router')
appServer.use(beyondRouter)
效果如下:
补充一下知识点: 回调函数
node_33.js的代码如下:
function NSLog(loli) {console.log(loli);return 'Copyright © 2018 Powered by beyond';};
function beyondFunction(callbackFunction){
setTimeout(
function(){
var girlSay = 'hello beyond'
// 为了能够在外部 拿到这个变量 girlSay 进行输出
// 我们使用回调函数
callbackFunction(girlSay)
},1000
)
}
// 这时我们调用beyondFunction时,只要传递一个block即可拿到定时器内的局部变量 girlSay
NSLog('准备执行函数beyondFunction')
beyondFunction(function ( result ) {
NSLog('what girl say is: ' + result)
})
NSLog('函数beyondFunction完毕')
运行效果如下:
为了使用自定义路由模块node_32_router.js 与 操作数据库 解耦,
并且同时发挥异步编程的先天优势,我们通过callback回调机制,
创建了一个Dao专门操作数据库的node_32_Dao.js
专门用来对文件数据库node_32.db进行CRUD增删改查
完整案例代码如下:
node_32_index.js代码如下:
function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}
// 导入框架
var express = require('express')
// 创建服务器对象
var appServer = express()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
if (error) {
return NSLog('启动失败: ' + error)
}
NSLog('服务启动成功')
})
// -----------------------------------
// 静态资源请求时的 staticFileUrlPrefix
var staticFileUrlPrefix = '/public/'
// var staticFileUrlPrefix = '/public'
// 访问也只能使用 localhost:5267/public/img/beyond.jpg
// 磁盘上的静态资源目录
var staticFilePath = './public/'
// var staticFilePath = 'public'
var callbackFunction = express.static(staticFilePath)
appServer.use(staticFileUrlPrefix,callbackFunction)
// -----------------------------------
// 指明:对于 所有后缀为html 的模板文件 使用模板引擎
var templateFileSuffix = 'html'
appServer.engine(templateFileSuffix,require('express-art-template'))
// 下面这一句参数配置,可有可无
appServer.set('view options',{
debug: process.env.NODE_ENV !== 'production'
})
// 注意:如果不想把模板文件放在默认的views目录下,则可以通过下面代码更改设置
// appServer.set('views','其他目录')
// -----------------------------------
// 使用middleware中间件body-parser进行post请求体中数据解析
var bodyParser = require('body-parser')
// 设置解析 application/x-www-form-urlencoded
appServer.use(bodyParser.urlencoded({extended: false}))
// 设置解析 application/json
appServer.use(bodyParser.json())
// -----------------------------------
// 自定义路由设计的目的是:
// 1.让主入口程序的职责更加单一,代码更加简洁
// 1.1 创建服务
// 1.2 做一些服务相关的配置,比如:
// 1.2.1 静态资源配置
// 1.2.2 模板引擎配置
// 1.2.3 body-parse 解析表单
// 1.2.4 挂载自定义路由
// 1.2.5 监听端口,启动服务
// 使用自定义的路由模块 必须使用./
// 注意: 配置模板引擎和body-parser, 一定要在挂载路由之前
var beyondRouter = require('./node_32_router')
appServer.use(beyondRouter)
路由模块node_32_router.js代码如下:
function NSLog(loli) {console.log(loli);return 'Copyright © 2018 Powered by beyond';};
/*
自定义路由模块的职责是:
专门处理所有的路由
根据不同的请求方式和路径,采取相应的处理方法
*/
// express 专门提供了路由的处理方法
var express = require('express')
// 1.使用express专门提供的路由器处理路由
var router = express.Router()
var fs = require('fs')
// ----------------首页-------------------
router.get('/',function (request,response) {
// 至于请求参数可以这样:
// var queryObj = request.query
// 第2个参数: 可以指定读取的编码
fs.readFile('node_32.db','utf8',function (error,data) {
if (error) {
return response.status(500).send('服务器内部错误')
}
// 将读取字符串,转成对象
var dataObject = JSON.parse(data)
// 使用模板引擎渲染
// 注意: 模板文件默认是放在views目录下
// 为此,我们在views目录下 分别为不同的业务模块创建了不同的文件夹
// 如 login登录 admin后台管理 index前台首页 article文章 comment评论
response.render('index/node_32_index.html',dataObject)
})
})
// ----------------添加的表单页面-------------------
router.get('/add',function (request,response) {
response.render('index/node_32_add.html')
})
// ----------------引入dao模块-------------------
// 先对dao初始化
var girlDao = require('./node_32_dao')
// 执行初始化函数,参数是一个block (即一个匿名回调函数callback),在读取数据库文件失败时,会回调
girlDao.loadDBFunction(function (error) {
NSLog('dao error: ' + error)
})
// ----------------增加一条记录-------------------
router.post('/insert',function (request,response) {
// 1.body-parser得到obj
var girlObj = request.body
NSLog(girlObj)
// 1.调用girlDao写到文件数据库
girlDao.addGirlFunction(girlObj,function (error) {
if (error === null) {
// 没有错误,跳转到首页
return response.redirect('/')
}
// 有错误
response.send(error)
})
})
// ----------------删除一条记录-------------------
router.get('/delete',function (request,response) {
// 1.获取query对象
var queryObj = request.query
NSLog('id: ' + queryObj.girlID)
// 2.调用dao从数据库中删除一个对象
girlDao.deleteModelByIDFunction(parseInt(queryObj.girlID),function (error) {
if (error === null) {
// 如果没有错误,跳转到首页
return response.redirect('/')
}
// 有错误
response.send(error)
})
})
// ----------------修改页面-------------------
router.get('/edit',function (request,response) {
// 查询的girlID
var queryObj = request.query
// 由于要根据指定的id查找出对象,所以通过dao
girlDao.findGirlByIDFunction(parseInt(queryObj.girlID),function (girl) {
if (girl === null) {
// 如果查找失败,则显示错误信息
return response.send('查无此人')
}
// 如果异步查找成功,则带着对象去渲染
return response.render('index/node_32_edit.html',{'girl':girl})
})
})
// ----------------更新数据库-------------------
router.post('/update',function (request,response) {
// 请求体
var postObj = request.body
// 使用dao进行更新
girlDao.updateGirlFunction(postObj,function (error) {
if (error) {
// 如果保存出错了
return response.send(error)
}
// 如果保存成功,回首页
response.redirect('/')
})
})
// 3.在模块文件最后,导出router
module.exports = router
数据库操作模块node_32_dao.js代码如下:
function NSLog(loli) {console.log(loli);return 'Copyright © 2018 Powered by beyond';};
var fs = require('fs')
var dbFilePath = 'node_32.db'
var DBFileObject = {}
// ----------------初始化-------------------
// 初始化,从磁盘中 读取数据文件,转成对象模型数组
exports.loadDBFunction = function (callback) {
// 第1步,读文件,转成对象数组
fs.readFile(dbFilePath,'utf8',function (error,data) {
// 第2步,在对象数组中,追加一个对象
if (error) {
// 出错了,回调给上层
callback('数据库文件读取失败')
}
// 直接转成对象
DBFileObject = JSON.parse(data)
})
}
// ----------------添加一条记录-------------------
exports.addGirlFunction = function (girl,callback) {
// 第1步,处理好girlID
DBFileObject.girlCount += 1
// 第2步,添加到数组末尾
girl.girlID = DBFileObject.girlCount
// 2.1 修正girlID
girl.girlAge = parseInt(girl.girlAge)
girl.pubTime = '2018-05-20'
DBFileObject.girlArr.push(girl)
// 第3步,保存到数据库文件,并回调
fs.writeFile(dbFilePath,JSON.stringify(DBFileObject),function (error) {
if (error) {
return callback('写入数据库失败')
}
// 写入文件成功
callback(null)
})
}
// ----------------删除一条记录-------------------
exports.deleteModelByIDFunction = function (girlID,callback) {
// 1.根据id,查找索引,删除对象
var deleteIndex = DBFileObject.girlArr.findIndex(function (girl) {
// 返回的条件是: 当两者id匹配成功之时
return girl.girlID === girlID
})
// 2.从数组中,通过指定下标,删除1个对象元素
DBFileObject.girlArr.splice(deleteIndex,1)
// 3.保存到数据库,并回调
fs.writeFile(dbFilePath,JSON.stringify(DBFileObject),function (error) {
if (error) {
return callback('写入数据库失败')
}
// 写入文件成功
callback(null)
})
}
// ----------------根据girlID查找一个对象-------------------
exports.findGirlByIDFunction = function (girlID,callback) {
// 1.查询出数据库里 对应 girlID的对象
var girl = DBFileObject.girlArr.find(function (item) {
// 返回的条件是: 当两者girlID相等
return item.girlID === girlID
})
// 回调
callback(girl)
}
// ----------------根据girlID查找一个对象-------------------
exports.updateGirlFunction = function (girl,callback) {
// 1.根据girlID查找
var targetGirl = DBFileObject.girlArr.find(function (item) {
return item.girlID === parseInt(girl.girlID)
})
NSLog('targetGirl: ' + targetGirl)
// 2.重新赋值
for(key in girl){
targetGirl[key] = girl[key]
}
// 2.1 修正girlID
targetGirl.girlID = parseInt(targetGirl.girlID)
targetGirl.girlAge = parseInt(targetGirl.girlAge)
// 3.重新写回数据库,并回调
fs.writeFile(dbFilePath,JSON.stringify(DBFileObject),function (error) {
NSLog('dao error : ' + error)
if (error) {
return callback('写入数据库失败')
}
// 写入文件成功
callback(null)
})
}
.
首页的模板node_32_index.html代码如下:
<!DOCTPYE html>
<html lang="zh">
<head>
<link rel="icon" href="/public/img/beyond2.jpg" type="image/x-icon"/>
<meta charset="UTF-8">
<meta name="author" content="beyond">
<meta http-equiv="refresh" content="520">
<meta name="description" content="未闻花名-免费零基础教程-beyond">
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
<meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY,XML,JSON,C,C++,C#,OC,PHP,JAVA,JSP,PYTHON,RUBY,PERL,LUA,SQL,LINUX,SHELL,汇编,日语,英语,泰语,韩语,俄语,粤语,阿语,魔方,乐理,动漫,PR,PS,AI,AE">
<title>beyond心中の动漫神作</title>
<link rel="stylesheet" type="text/css" href="/public/css/beyondbasestylewhite5.css">
<script type="text/javascript" src="/public/js/nslog.js"></script>
<!--[if lt IE 9]>
<script src="//apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">
</script>
<![endif]-->
<style type="text/css">
body{
font-size: 100%;
/*声明margin和padding是个好习惯*/
margin: 0;
padding: 0;
background-image: url("/public/img/sakura4.png");
background-repeat: no-repeat;
background-position: center center;
}
</style>
<!-- 绿色按钮的css效果 -->
<link rel="stylesheet" type="text/css" href="/public/css/beyondbuttongreen.css">
<!-- 引入 jquery 2.1.4 -->
<!--[if gte IE 9]><!-->
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js">
</script>
<!--<![endif]-->
<link rel="stylesheet" type="text/css" href="/public/lib/bootstrap/bootstrap.css">
<!-- 分隔线 -->
<!-- Bootstrap core CSS -->
<link href="/public/lib/node30_337_bootstrap.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="/public/css/node30dashboard.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<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">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#" style="color:white;">beyond</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Dashboard</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Help</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search...">
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
<li><a href="">More navigation</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header" style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">未闻花名<small><a href="/add" style="color:white">添加记录(Node版)</a></small></h1>
<!-- <div class="row placeholders">
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
</div> -->
<!-- <h2 class="sub-header">动漫神作列表 </h2> -->
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>id</th>
<th>芳名</th>
<th>年龄</th>
<th>动漫</th>
<th>日期</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{ each girlArr }}
<tr>
<td>{{ $value.girlID }}</td>
<td>{{ $value.girlName }}</td>
<td>{{ $value.girlAge }}</td>
<td>{{ $value.girlDescription }}</td>
<td>{{ $value.pubTime }}</td>
<td>
<button class="btn btn-success"><a href="/edit?girlID={{ $value.girlID }}" style="color:white;">修改</a></button>
<button class="btn btn-danger"><a href="/delete?girlID={{ $value.girlID }}" style="color:white;">删除</a></button>
</td>
</tr>
{{ /each }}
</tbody>
</table>
</div>
</div>
</div>
</div>
<footer id="copyright">
<p style="font-size:14px;text-align:center;font-style:italic;">
Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>
</p>
</footer>
</body>
</html>
添加记录的模板node_32_add.html代码如下:
<!DOCTPYE html>
<html lang="zh">
<head>
<link rel="icon" href="/public/img/beyond2.jpg" type="image/x-icon"/>
<meta charset="UTF-8">
<meta name="author" content="beyond">
<meta http-equiv="refresh" content="520">
<meta name="description" content="未闻花名-免费零基础教程-beyond">
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
<meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY,XML,JSON,C,C++,C#,OC,PHP,JAVA,JSP,PYTHON,RUBY,PERL,LUA,SQL,LINUX,SHELL,汇编,日语,英语,泰语,韩语,俄语,粤语,阿语,魔方,乐理,动漫,PR,PS,AI,AE">
<title>beyond心中の动漫神作</title>
<link rel="stylesheet" type="text/css" href="/public/css/beyondbasestylewhite5.css">
<script type="text/javascript" src="/public/js/nslog.js"></script>
<!--[if lt IE 9]>
<script src="//apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">
</script>
<![endif]-->
<style type="text/css">
body{
font-size: 100%;
/*声明margin和padding是个好习惯*/
margin: 0;
padding: 0;
background-image: url("/public/img/sakura4.png");
background-repeat: no-repeat;
background-position: center center;
}
</style>
<!-- 绿色按钮的css效果 -->
<link rel="stylesheet" type="text/css" href="/public/css/beyondbuttongreen.css">
<!-- 引入 jquery 2.1.4 -->
<!--[if gte IE 9]><!-->
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js">
</script>
<!--<![endif]-->
<link rel="stylesheet" type="text/css" href="/public/lib/bootstrap/bootstrap.css">
<!-- 分隔线 -->
<!-- Bootstrap core CSS -->
<link href="/public/lib/node30_337_bootstrap.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="/public/css/node30dashboard.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<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">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#" style="color:white;">beyond</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Dashboard</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Help</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search...">
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
<li><a href="">More navigation</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header" style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">未闻花名<small><a href="/" style="color:white;">回到首页</a></small></h1>
<div class="row placeholders">
<!-- <div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div> -->
</div>
<!-- <h2 class="sub-header">动漫神作列表 </h2> -->
<form action="/insert" method="post">
<div class="form-group">
<label for="in_input_name">芳名</label>
<input type="text" class="form-control" id="in_input_name" placeholder="请输入妳的名字" name="girlName">
</div>
<div class="form-group">
<label for="id_input_age">年龄</label>
<input type="text" class="form-control" id="id_input_age" placeholder="请输入妳的芳龄" name="girlAge">
</div>
<div class="form-group">
<label for="id_input_anime">动漫推荐</label>
<input type="text" class="form-control" id="id_input_anime" placeholder="请输入妳主演过的动漫" name="girlDescription">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<footer id="copyright">
<p style="font-size:14px;text-align:center;font-style:italic;">
Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>
</p>
</footer>
</body>
</html>
修改(回显)记录的模板node_32_edit.html代码如下:
<!DOCTPYE html>
<html lang="zh">
<head>
<link rel="icon" href="/public/img/beyond2.jpg" type="image/x-icon"/>
<meta charset="UTF-8">
<meta name="author" content="beyond">
<meta http-equiv="refresh" content="520">
<meta name="description" content="未闻花名-免费零基础教程-beyond">
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
<meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY,XML,JSON,C,C++,C#,OC,PHP,JAVA,JSP,PYTHON,RUBY,PERL,LUA,SQL,LINUX,SHELL,汇编,日语,英语,泰语,韩语,俄语,粤语,阿语,魔方,乐理,动漫,PR,PS,AI,AE">
<title>beyond心中の动漫神作</title>
<link rel="stylesheet" type="text/css" href="/public/css/beyondbasestylewhite5.css">
<script type="text/javascript" src="/public/js/nslog.js"></script>
<!--[if lt IE 9]>
<script src="//apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">
</script>
<![endif]-->
<style type="text/css">
body{
font-size: 100%;
/*声明margin和padding是个好习惯*/
margin: 0;
padding: 0;
background-image: url("/public/img/sakura4.png");
background-repeat: no-repeat;
background-position: center center;
}
</style>
<!-- 绿色按钮的css效果 -->
<link rel="stylesheet" type="text/css" href="/public/css/beyondbuttongreen.css">
<!-- 引入 jquery 2.1.4 -->
<!--[if gte IE 9]><!-->
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js">
</script>
<!--<![endif]-->
<link rel="stylesheet" type="text/css" href="/public/lib/bootstrap/bootstrap.css">
<!-- 分隔线 -->
<!-- Bootstrap core CSS -->
<link href="/public/lib/node30_337_bootstrap.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="/public/css/node30dashboard.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<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">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#" style="color:white;">beyond</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Dashboard</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Help</a></li>
</ul>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search...">
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
<li><a href="">More navigation</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header" style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">未闻花名<small><a href="/" style="color:white;">回到首页</a></small></h1>
<div class="row placeholders">
<!-- <div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div> -->
</div>
<!-- <h2 class="sub-header">动漫神作列表 </h2> -->
<form action="/update" method="post">
<div class="form-group">
<label for="in_input_name">芳名</label>
<input type="text" class="form-control" id="in_input_name" placeholder="请输入妳的名字" name="girlName" value="{{ girl.girlName }}">
</div>
<div class="form-group">
<label for="id_input_age">年龄</label>
<input type="text" class="form-control" id="id_input_age" placeholder="请输入妳的芳龄" name="girlAge" value="{{ girl.girlAge }}">
</div>
<!-- 隐藏表单 -->
<input type="hidden" name="girlID" value="{{ girl.girlID }}" />
<div class="form-group">
<label for="id_input_anime">动漫推荐</label>
<input type="text" class="form-control" id="id_input_anime" placeholder="请输入妳主演过的动漫" name="girlDescription" value="{{ girl.girlDescription }}">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<footer id="copyright">
<p style="font-size:14px;text-align:center;font-style:italic;">
Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>
</p>
</footer>
</body>
</html>
项目运行效果如下:
未完待续,下一章节,つづく