NodeJs——(16)用Nodejs 4.X版本,制作一个微博网站(多图,详细步骤)
①内容较长,我会尽力把整个框架、结构、顺序、思考方式说明白。
②基础是《node.js开发指南》这本书,作者:BYVoid。但他书的版本较老,很多东西现在已经无法应用,故进行更新,使用目前普遍的express 4.x版本(原书似乎是2.X版本),mysql(原书是mongodb),jade(原书是ejs)
【1】基本需求:
①有首页;
②支持注册;
③支持登录、登出;
④可以发表博客,发表的博客可以保存到数据库;
⑤可以查看博客,博客从数据库中读取,为了简化,这里设置为查看所有人的博客;
⑥查看博客时,初始查看的数量有限,但可以无限加载新的博客,直到查看完全部博客;
⑦一定程度上实现多语言(即可以切换显示的语言版本),但由于复杂度所限,因此只部分实现(但框架已建立好,可以通过继续完善代码实现整体的国际化);
⑧根据登录状态,对可以访问的页面进行控制(某些允许某些禁止)
【2】前后端交互的简单过程:
【3】关于客户端请求的几种情况(涉及到数据库的)
【4】npm
npm是包管理器,在新版本里是默认安装好的,可以输入:
npm -v
来查看npm的版本
【5】express框架:
首先安装基础的express框架,他是封装好的web开发框架,里面包含了:
①路由控制、
②log显示、
③解析客户端请求、
④cookies解析、
⑤静态文件的控制
等多种功能。
安装前注:
①有的人只需要简单的
npm install -g express
npm install -g express-generator
就可以愉快的跑起express了,有的人就像向我一样苦逼,尝试各种办法,最后勉强可以用。
如果在这两行命令后,输入(V是大写的)
express -V
会返回版本号,那么直接跳到最后来看,如果不是这样,可以参考我写的记录来安装。
或者直接看后面的终极解决方案
②express设置全局方法:
ln -s /usr/nodejs4.4.7/node-v4.4.7-linux-x64/bin/express /usr/local/bin/express
其他需要全局的方法,理论上同理,即将nodejs安装目录下的bin文件夹下的模块,映射到/usr/local/bin/同名文件即可
③express命令可以使用的人:
输入:
express -t jade myblog
效果是建立一个文件夹名为myblog的文件夹,里面会有一些文件。
正常如下图:
cd myblog
npm install
这时,npm会根据package.json来安装一些东西。
按提示输入:
SET DEBUG=myblog:*
npm start
可以启动项目。
本机的话,通过访问http://127.0.0.1:3000/ 来查看效果
服务器的话,访问其公网ip,端口是3000
查看package.json
"scripts": { "start": "node ./bin/www" },
这条属性告诉我们,需要通过bin文件夹下的www来启动,这也就是上面npm start命令的作用。
www文件应该是设置自启动的,然而我这里并不需要。但若直接启动app.js是启动不了的,因为在www文件里面,设置了端口是3000,他是通过www文件来启动监听的。
解决办法:
在app.js里面,在最后一行代码之前,添加:
app.listen(80);
于是,便可以通过app.js来启动服务器了。
访问效果如图:
假如如果像我一样倒霉,无法用express命令,打开npm也特别慢,可以先找个系统,将这些文件下载好,然后将这些文件复制到不可以用express命令的linux系统下面。
或者看最后的终极解决方案
ps:
如果npm很慢的话,可以考虑装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
然后在npm install这一步,使用cnpm install来替代
————————分割线————————
④超级终极解决方案:
我传一个装好express的压缩包,直接解压缩后就可以用。
链接:
http://download.csdn.net/detail/qq20004604/9587054
⑤另一个启动方法
即不通过app.js来启动;
在之前④的基础上,打开app.js,删除
app.listen(80);
打开package.json,将
"start":"node ./app.js"
改回
start":"node ./bin/www"
然后
cd bin
vi www
将
var port =normalizePort(process.env.PORT||3000);
修改为
var port =normalizePort(process.env.PORT||80);
然后
cd ..
npm start
启动成功,可以直接访问地址来访问页面
【6】把启动的app.js放在后台运行,并且在操作端解除控制后依然可以运行
原本使用npm start的地方,输入
nohup npm start
即可
【7】app.js之解释
app.js可以说是一切的根本,因此请看注释,解释了每行代码的作用:
var express = require(express); //这个模块在node_modules文件夹中 var path = require(path); //nodejs自带的,路径相关 var favicon = require(serve-favicon); //node_modules文件夹中 var logger = require(morgan); //日志相关,node_modules文件夹中,具体看第19行代码 var cookieParser = require(cookie-parser);//node_modules文件夹中,用来解析cookie的,被express所调用 var bodyParser = require(body-parser); //用于解析请求体的(应该),被express所调用 var routes = require(./routes/index); //这里是默认的路由,路径是routes/index.js var users = require(./routes/users); //这里是默认的路由,路径是routes/users.js //关于路由的更多内容看下面的app.use(/, routes);和app.use(/users, users);的注释 var app = express(); //生成一个express的实例 //设置模板引擎 app.set(views, path.join(__dirname, views)); //__dirname表示绝对路径 //console.log(__dirname) //可以取消这一行注释,然后看看__dirname的效果 app.set(view engine, jade); //表示express是使用jade格式的模板的
//下面这行代码是设置左上角的小图标的,将其命名为favicon.ico并放在public文件夹下,如果有的话,取消这行注释 //app.use(favicon(path.join(__dirname, public, favicon.ico))); app.use(logger(dev)); //设置日志显示,如果不需要的话可以注释掉这行代码,建议练手的时候不要注释掉 //可替换参数有default,combined,common,short,tiny,dev(相对tiny有染色)。可以自己试试效果,默认是dev app.use(bodyParser.json()); //解析客户端的请求,通常是通过post发送的内容 app.use(bodyParser.urlencoded({extended: false})); //另一种解析方式,具体不太明白(如果上面解析失败的话会通过这个来) app.use(cookieParser()); //cookies的解析 app.use(express.static(path.join(__dirname, public))); //普通静态html文件、js文件、css文件,都放在public文件夹下,可以直接通过url来访问 //路由的处理 app.use(/, routes); //假如访问的网址是根目录,例如http://121.41.66.68/,交给routes这个js文件来处理,具体请查看routes app.use(/users, users); //假如访问的是/users这样的路径,那么交给users这个js文件来处理,具体略 //我们最后要对这个路由进行处理,让他按照我们想要的方式来做 //这里对非法路径进行处理的,next表示这是一个中间件(即执行完他之后,还会执行下一个,而不是直接在这里结束了) //如果上面没有静态文件(29行)、没有找到被路由处理的文件(32,33行),就会交给这个来处理。 app.use(function (req, res, next) { var err = new Error(Not Found); err.status = 404; next(err); //由下面的2个app.use中的一个来处理(一般是第一个,除非第一个被注释)
//原注释说是会对错误进行加亮处理 //这部分和下面的区别在于,这部分会将错误信息暴露给用户,而下面的不会,因此注释掉这部分 //if (app.get(env) === development) { // app.use(function (err, req, res, next) { // res.status(err.status || 500); // res.render(error, { // message: err.message, // error: err // }); // }); // production error handler // no stacktraces leaked to user app.use(function (err, req, res, next) { res.status(err.status || 500); res.render(error, { //这里的error指调用views下的error模板 message: err.message, error: {} //这是我自行添加的,用于显示服务器启动的时间 console.log("Server start at :" + new Date()); //导出app,在./bin/www里会被调用 module.exports = app;
【8】页面关系结构
请忽略文件名的大小写问题(手动微笑)
因此,首先有三个需要我们自定义的路由:
①当访问根/时,输出index;
②当访问/login时,输出login
③当访问/reg时,输出reg
其他可能的路由:
④后续可能添加的页面,暂缺;
⑤不符合要求的页面,输出404(express已经完成)
【9】index页面需要包含的功能:
【10】index的路由:
查看app.js中的代码:
app.use(/, routes);
这部分代码已经说明了,当访问根的时候,交给routes来处理;
再次查看导入routes的地方:
var routes = require(./routes/index);
说明负责这部分的文件是routes文件夹的index文件
这时打开index.js,
router.get(/, function(req, res, next) { res.render(index, { title: Express }); });
这部分代码,表示当访问根的 ’/’ 页面时,由index这个引擎模板来处理,模板中的title变量,其值为Express。
————————————————————————
代码说明:
router.get(/
以上这段代码是在路由基础上进行二段捕获url的,举例:
①假如在app.js里,
app.use(/,
然后在路由的处理里,是
outer.get(/
那么最终针对的url是/
②假如在app.js里,
app.use(/test,
然后在路由的处理里,是
outer.get(/
那么最终针对的url是/test
③假如在app.js里,
app.use(/,
然后在路由的处理里,是
outer.get(/test
那么最终针对的url依然是/test
④假如在app.js里,
app.use(/testA,
然后在路由的处理里,是
outer.get(/testB
那么最终针对的url是/testA/testB
⑤捕获优先度说明:
首先根据app.js中的app.use出现顺序决定,假如②和③同时出现,那么看②和③在app.js中的代码谁先出现,就交给谁来处理;
再不调用next()方法的情况下,只会被最先出现的那个处理;
如果第一个调用了next()方法,那么第一个处理完后会执行第二个的
————————————————————————
index.js代码说明:
var express = require(express); //调用express var router = express.Router(); //生成express的Router方法的一个实例 //处理函数 router.get(/, function (req, res, next) { //捕获根url res.render(index, {title: Express}); //res.render方法渲染一个引擎模板, //第二个参数是一个对象,对象里的变量可以在引擎中使用, //第三个参数是回调函数,提供两个参数,分别是err和html,err是错误,html是渲染后的页面。如果使用这个回调函数,那么将不会自动响应,即要用户自己写返回html的命令 module.exports = router;
注意,被引擎渲染的文件,默认是在myblog/views文件夹下
【11】使用Bootstrap界面
让我们自己设计界面不是不可以,不过太麻烦,因此我和原书保持一致,使用Twitter Bootstrap风格的页面。
下载他的压缩包文件,并解压缩他,
将css文件放在项目myblog/public/stylesheets下;
将img文件夹直接复制粘贴在myblog/public下;
将js文件放在myblog/public/javascripts下,
我的Bootstrap的版本是v2.3.2
另外,下载jquery,命名为jq.js,放在myblog/public/javascripts下
【12】index.jade说明
下来我们就要修改jade文件了,如果不知道怎么使用的话,可以看我的博客:
http://blog.csdn.net/qq20004604/article/details/51773574
extends layout block content h1= title p Welcome to #{title}
第一行的extends layout表示他导入的layout模板(即layout.jade)
block content表示以下这部分将套入layout的content位置
内容略。
这时候再过去看layout.jade
doctype html head title= title link(rel=stylesheet, href=/stylesheets/style.css) body block content
他导入的是style.css这个样式表,页面的title是变量title
上面的index.jade中的内容将导入这里的block content区域(因为变量名一样,会对应替换)。
其结构大概如下:
然后我们根据自己实际需求来改造:
直接给出代码:
首先在stylesheets文件夹下创建一个blog.css文件,内里样式为:
body { padding-top: 60px; padding-botom: 40px; #textarea { resize: none; width: 300px; height: 100px; cursor: text; #postBlog { position: relative; left: 20px; vertical-align: top; #clearBlog { position: relative; left: -90px; top: 27px; width: 110px; height: 44px; .myalert { position: absolute; .displayNONE { display: none; #scrollToFoot { border: 1px solid #ccc; text-align: center; font-size: 18px; padding: 20px 0; fotter p { margin-top: 40px; padding-top: 20px; border-top: 1px solid #aaa; font-size: 18px; .row { color: #555; }
其次是layout.jade
doctype html head title MyBlog By qq20004604 link(rel=stylesheet, href=./stylesheets/bootstrap.min.css) link(rel=stylesheet, href=./stylesheets/bootstrap-responsive.min.css) link(rel=stylesheet, href=./stylesheets/blog.css) script(type="text/javascript",src=javascripts/jq.js) script(type="text/javascript",src=javascripts/bootstrap.min.js) script(type="text/javascript",src=javascripts/blog.js) body div.navbar.navbar-fixed-top div.navbar-inner div.container a.btn.btn-navbar(data-toggle="collapse",data-target=".nav-collapse") span.icon-bar span.icon-bar span.icon-bar a.brand(href="/") MyBlog div.nav-collapse ul.nav a(href="/") 首页 a(href="/logout") 登出 a(href="/login") 登入 a(href="/reg") 注册 a(href="/language") 切换语言 div#contrainer.container block content fotter p 作者:王冬 QQ:20004604
效果如图:
然后是index.jade:
extends layout block content div.hero-unit h1 我的博客 p 这个是基于Nodejs作为后台,jade作为模板来,使用了Express作为框架 //这部分暂时用1替代,后续会被更新 if(1) a.btn.btn-primary.btn-large(href="/login") 登录 a.btn.btn-large(href="/reg") 立即注册 else textarea#textarea.uneditable-input button#postBlog.btn.btn-large 提交微博 button#clearBlog.btn.btn-large 清空 div#submitError.alert.alert-error.displayNONE.myalert div#submitSuccess.alert.alert-success.displayNONE div.row.content div.span4 h2 烟雨江南说 p 当欲望没有了枷锁,就没有了向前的路 p 只有转左,或者向右 p 左边是地狱,右边也是地狱 div.span4 h2 烟雨江南说 p 那些都是极好极好的 p 可是我偏偏不喜欢 div.span4 h2 烟雨江南说 p 我不怕傻 p 只怕 p 遇不到 p 可以让我变傻的人 div.span4 h2 烟雨江南说 p 人在年轻的时候总会有些莫名的坚持, p 并且以此感动着自己, p 却时常会在不经意间让真正重要的东西从指间流走。 div.span4 h2 烟雨江南说 p 记忆真是一种奇怪的东西, p 有时候会涤荡所有的苦难,只留下温情, p 有时候却磨灭掉曾有的欢乐,唯剩下苍白和丑陋。 div.span4 h2 烟雨江南说 p 那存在的,都是幻影。 p 那永恒的,终将毁灭。 p 世界万物,缤纷色彩,都是被蒙蔽的人心罢了。 div.span4 h2 烟雨江南说 p 诸神以真相示人,而世人却视而不见 div.span4 h2 烟雨江南说 p 只有绵羊会向狮子要求平等, p 而狮子们从来不会这样想。 div.span4 h2 烟雨江南说 p 愿迷途的旅人,从此得享安息。 p 因理想而不朽,因归返而救赎。 div#scrollToFoot 滚动到底部然后加载内容
效果如图:
但此时,上面的页面切换目前还都是无效状态;
滚动然后加载内容,也正处于无效状态;
注册和登录按钮,点击后也无法正常跳转;
我们需要依次解决这些问题。
【13】登录页面
接下来我们添加登录页面的路由和模板。
路由,打开app.js,在
app.use(/, routes); app.use(/users, users);
之前添加
var reg = require(./routes/reg); var login = require(./routes/login);
之后添加:
app.use(/reg, reg); //注册的,reg.js来处理 app.use(/login, login); //登录的,login来处理
这样的话,就添加了注册和登录页面的路由了,但目前,我们还缺其具体文件和代码。
进入routes文件夹,创建reg.js和login.js
reg.js
var express = require(express); //调用express模块 var router = express.Router(); //调用模块的Router方法 router.get(/, function (req, res, next) { res.render(reg) module.exports = router;
login.js
var express = require(express); //调用express模块 var router = express.Router(); //调用模块的Router方法 router.get(/, function (req, res, next) { res.render(login) module.exports = router;
现在又缺模板文件了。
进入views文件夹,创建reg.jade和login.jade
reg.jade
extends layout block content form.form-horizontal(method="post") fieldset legend 注册 div.control-group label.control-label(for="username") 用户名 div.controls input.input-xlarge#username(type="text",name="username") p.help-block 你的账户名称,用于登录和提示 div.control-group label.control-label(for="password") 口令 div.controls input.input-xlarge#password(type="password",name="password") div.control-group label.control-label(for="password-repeat") 重复输入口令 div.controls input.input-xlarge#password-repeat(type="password",name="password-repeat") div.form-actions button.btn.btn-priamry(type="submit") 注册
login.jade
extends layout block content form.form-horizontal(method=post) fieldset legend 登录 div.control-group label.control-label(for=username) 用户名 div.controls input.input-xlarge#username(name=username,type=text) div.control-group label.control-label(for=password) 密码 div.controls input.input-xlarge#password(name=password,type=password) div.form-actions button.btn.btn-primary(type="submit") 登录
这个时候,注册和登录页面已经可以访问了(虽然还没有添加逻辑)
VSCode安装配置使用教程(最新版超详细保姆级含插件)一文就够了 Visual Studio Code 是一个轻量级功能强大的源代码编辑器,支持语法高亮、代码自动补全(又称 IntelliSense)、代码重构、查看定义功能,并且内置了命令行工具和 Git 版本控制系统。适用于 Windows、macOS 和 Linux。它内置了对 JavaScript、TypeScript 和 Node.js 的支持,并为其他语言和运行时(如 C++、C#、Java、Python、PHP、Go、.NET)提供了丰富的扩展生态系统。为了不影响读者的沉浸式阅读学习,如需使用目录请在左侧使用即可。
微信小程序--》小程序简介与工具安装配置 经过web前端开发的学习,相信大家对于前端开发有了一定深入的了解,今天我开设了微信小程序,主要想从移动端开发方向进一步发展,而对于我来说写移动端博文的第一站就是小程序开发,希望看到我文章的朋友能对你有所帮助。
用 NodeJS 开发一版在线流程图网站 体验:http://cp.maqib.cn/ 对于程序员来说,每天除了写代码,接触较多的可能是各种图表了,诸如流程图、原型图、拓扑图、UML 图以及思维导图等等,我们较为熟悉的是 ProcessOn了
通过nodejs实现网易云音乐批量下载或单曲下载 从豆瓣转到网易云后,发现了不少好听的歌曲,然鹅..当我想把这些歌拿下来扔车上听的时候发现竟然不允许下载..能听不能下?这不科学,作为一名程序猿,必然要迎难而上啊.
YouTube下载视频教程:常用的网站软件插件APP都有涉及 有时候可能需要YouTube上的视频来进行一些操作,比如教程演示,语言学习,视频编辑等.....那么YouTube视频怎么下载下来呢?方法比较多。在这篇文章里我会给大家介绍一些下载YouTube视频的常用网站、浏览器插件、电脑软件和手机APP,方便大家找到最合适的方法去保存油管视频。
相关文章
- 浅谈Nodejs应用的主文件index.js的组成部分
- 利用angular4和nodejs-express构建一个简单的网站(七)—用户注册之ReactiveForm
- Nodejs学习路线图
- window下Nodejs的部署
- nodejs XML和json互相转换
- Nodejs使用robot操作鼠标键盘
- 【收藏】nvm的下载,安装与使用(nodejs版本管理)
- Atitit nodejs5 nodejs6 nodejs 7.2.1 新特性attialx总结
- nodejs连接mysql数据库
- 使用nodejs&webpack&vue-cli脚手架工具搭建项目
- NodeJs——(10)REST风格的路由规则
- NodeJs——(7)request的结构
- nodejs xpath
- ActiveMQ + NodeJS + Stomp 极简入门
- nodejs的__dirname与__filename
- NodeJS+Express+MongoDB
- Nodejs实现爬虫抓取数据
- 学习NodeJS第一天:node.js引言
- nodejs 安装
- CoinHive挖矿原理分析——后端是nodejs服务,前端直接miner.start即可