第一步:安装express框架javascript
命令行转到node.exe的目录下,使用命令:npm install express。
css
而后新建一个文件夹test用来放咱们的项目,里面新建一个文件index.js,做为入口文件,内容为:
html
var express = require('express'); var app = express(); app.get('/', function (request, response) { //express框架处理get请求 response.send('Hello World!'); }); app.listen(80); //命令行切换到index.js的目录,用node index.js启动后,在浏览器访问http://localhost,便可看到结果
至于为何项目要放在这,主要是由于require加载模块可以找获得,固然,假如你把express框架拷贝一份或者用绝对路径,那么就能够把咱们的项目放在任何地方了。require加载模块的搜索方式具体请参照《node.js开发指南》6.1.3章。
java
等等,上面的例子处理get请求好像没没涉及到数据的获取吧。。。搜噶,往下。。。
node
处理get请求mysql
var express = require('express'); var app = express(); app.get("*", function(req, res) { //获取数据的格式一为:req.query.参数名; var id = req.query.id; //1 var myName = req.query.my.name; //zhangsan //获取数据的格式二为:req.param("n");或者req.param.n; var id_copy = req.param('id'); //1 var myName_copy = req.param('my'); //{ name: 'zhangsan', address: 'beijing' } //另外,还能够用req.param('n')拿到路径中的对象。假如第一个参数不传"*",而传"/test/:hehe" //var t = req.param('hehe'); //浏览器访问:http://localhost/test/lisi 则t=lisi res.send("测试"); }); app.listen(80); //假设在浏览器访问的url为:http://localhost?id=1&my[name]=zhangsan&my[address]=beijing
request.param():能够处理get和post请求参数,但查找优先级由高到低为:req.params→req.body→req.query。jquery
处理post请求ajax
与处理get请求同样
sql
响应mongodb
//格式为:res.send([body|status], [body]); //当参数为一个String时,Content-Type默认设置为"text/html"。 res.send('Hello World'); //Hello World 当参数为Array或Object时,Express会返回一个JSON。 res.send({ user: 'tobi' }); //{"user":"tobi"} res.send([1,2,3]); //[1,2,3] //.当参数为一个Number时,而且没有上面提到的任何一条在响应体里,Express会帮你设置一个响应体,好比:200会返回字符"OK"。 res.send(200); // OK res.send(404); // Not Found res.send(500); // Internal Server Error
这点超赞~返回数组和对象时,express框架自动帮转化为json数据。
第二步:安装mongoDB数据库
首先去官网下载(http://www.mongodb.org/downloads)压缩包(.zip的哦)。
而后解压出来,里层有个bin文件夹。
接着找个地方放好(无需安装版的,建议放非C盘),打开命令行,进入到里面那个bin目录(我是解压后更名为mongodb,因此个人目录是:D:\mongodb\bin)
执行:mongod.exe --logpath=D:\mongodb\log.txt --dbpath=D:\mongodb\db
--logpath 参数是设定日志文件的路径。
--dbpath 参数是设定数据库文件的存放路径。
mongod.exe命令的全部参数选项可经过mongod.exe --help查看。
到此其实mongodb已经安装完成,不过每次都要打开黑窗口执行这句命令而且黑窗口不能关,比较烦~~~so,咱们能够把mongodb做为服务安装(比如mySQL同样,要用mysql同样是要开启mysql服务)。在D:\mongodb\bin下,执行:mongod.exe --install --logpath=D:\mongodb\log.txt --dbpath=D:\mongodb\db。
最后看到了对应的服务,之后只要启动此服务便可。
net start mongodb 启动mongodb服务
net stop mongodb 启动mongodb服务
PS:测试方法以下
var express = require('express'); var app = express(); var mongoose = require("mongoose"); var db = mongoose.connect("mongodb://127.0.0.1:27017/test"); db.connection.on("error", function (error) { console.log("数据库链接失败:" + error); }); db.connection.on("open", function () { console.log("------数据库链接成功!------"); }); app.listen(80);
第三步:动手
首先新建一个文件夹放项目,个人目录结构以下图:
models:用来放mongoose的模式、模型,如user模型等
node_modules:这个在你安装模块时会自动生成,也可手动建立,用来放模块,如express模块等
public:用来放静态资源,如页面用到的css和公用js等
routes:用来放路由文件,固然你把路由全写在app.js里也没人说你错。。。
schema:原本是用来放mongoose的模式文件的,我把模式和模型合并放在models了,因此不用此文件夹了
views:用来放视图文件,也就是前台显示的页面
根目录的app.js:程序入口文件
根目录的db_connect.js:链接数据库的公用文件
根目录的npm-debug.log:自动生成的npm调试日志文件
而后冲入口文件app.js下手(/app.js)
var express = require('express'); var bodyParser = require('body-parser'); //已经从express中分离出来,依赖模块:body-parser var session = require('express-session'); var moment = require('moment'); var app = express(); // 只用于开发环境 if ('development' == app.get('env')) { app.set('db uri', 'localhost/dev'); } // 只用于生产环境 if ('production' == app.get('env')) { app.set('db uri', 'n.n.n.n/prod'); } //设置端口 app.set('port', process.env.PORT || 80); //选择视图模版,并把后缀由.ejs转换为.html app.set( 'views', 'ejs' ); app.set( 'view engine', 'html' ); app.engine( '.html', require( 'ejs' ).__express ); //指定视图存放位置 app.set('views', require('path').join(__dirname, 'views')); //指定静态资源存放位置 app.use(express.static(require('path').join(__dirname, 'public'))); app.use(bodyParser()); //中间件body-parser和multer用于处理和解析post请求的数据 app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); //文件上传中间件 // app.use(multer()); //启用session app.use(session({ key:'session_overtime_30min', secret:'session_secret', resave:true, saveUninitialized:false, cookie:{ maxAge:1000*60*5 //session过时时间设置(单位毫秒) } })); app.use(function(req, res, next){ //这里写处理逻辑 next(); }); //routes 路由选择 var routes = require('./routes'); routes(app); //启动服务 app.listen(app.get('port'),function(){ console.log("【时间】:"+moment().format('YYYY-MM-DD HH:mm:ss')); console.log("【状态】:服务器已启动,端口:"+app.get('port')); });
稍微解释下:
require引入所需的模块,会优先从刚才的node-modules文件夹里找,假如没有才逐级网上找,直到全局。
app.set(...),对express框架的一些设置。
app.use(...),express框架的中间件,用next()传递。(PS:有点像java里面的过滤器)
routes(app),把路由分发处理。固然,路由少的话能够直接把路由处理写在app.js里。
app.listen(...),启动程序监听端口。
而后进入路由分发:(routes/index.js)
/** * 路由分发 */ require('../db_connect'); var user = require('./user'); var admin = require('./admin'); var Inform = require('../models/inform'); var Room = require('../models/room'); var Meeting = require('../models/meeting'); var moment = require('moment'); module.exports = function(app){ //前台首页 app.get('/',function(req,res){ //通知概要 Inform.find({"level":"A"}, null, {"limit":3,"sort":{"time":-1}}, function(err, user){ //举例子怎么拿到请求中的数据 //var n = req.query.n || ""; //假如请求的内容是/?n=1,则n=1 if (err) { console.log(err); }else{ Inform.find({"level":"B"}, null, {"limit":5,"sort":{"time":-1}}, function(err, docs){ res.render('index', {"title":"首页","active": "index","user":req.session.user,"inform_summary":{"A":user,"B":docs}}); }); } }); }); user.routes(app); admin.routes(app); }
代码解释:
require('../db_connect')这是直接把db_connect.js文件插入到此,文件内容为:(、db_connect.js)
var mongoose = require('mongoose'); mongoose.connect("mongodb://127.0.0.1:27017/my");
app.get(请求路径,处理请求和响应的函数):处理对应的get请求。
Inform.find(...):Inform是一个模式,能够直接执行mongo的sql语句,下一步看模式文件。
req:是http中的request,经express框架处理后包含了请求体的所有信息。
res:是http中的response,经express框架处理后的响应体。
res.send(返回的数据):能够返回数据给刚才的请求。
res.render(模版文件名,数据):能够渲染模版而后模版渲染好后自动返回给前台。稍后看模版文件。
user.route(app):以及下面的都是路由分发,这里不处理那么多,交给其余路由文件处理,这是分类思想。
刚才有模式文件和模版文件没晓得是什么,那咱们先看模式文件:(models/inform.js)
var mongoose = require('mongoose'); var InformSchema = new mongoose.Schema({ title: { type: String}, content: { type: String}, level: { type: String}, from:{ type: String}, time: { type: String, default: new Date() } }); //模式的静态方法,只有进行模型实例化后才可用的方法 InformSchema.pre('save',function(next){ //pre方法是在sava以前执行,不会与数据库进行交互。 next(); }); InformSchema.statics = { findAll: function(cb) { return this.find({}).sort({'time':-1}); exec(cb); }, findByKeyword: function(e, cb) { return this.find({$or:[{title:/^B.*/},{content:/^B.*/}]}).sort({'time':-1}); exec(cb); } }; module.exports = mongoose.model('Inform',InformSchema);
代码解释:
var mongoose = require('mongoose'):引入mongoose模块。
new mongoose.Schema({}):建一个Schema(模型),而后把这个模型赋给InformSchema变量。
InformSchema.pre():定义一些在模型实例化为模式以前的处理。
InformSchema.statics:定义一些在执行模式中的方法时的中间处理,只有在模式实例化为模型才可用。
module.exports = mongoose.model('Inform',InformSchema):实例化模式变为模型,对外公开为Inform。
PS:有的人喜欢把模式单独写为一个文件,而后在这里引入再实例化为模型,我以为不必,因此合并在一块儿写了。
呵呵,到这你应该看得懂刚才路由分发中的Inform.find(条件,[过滤条件],回调)这里的函数了吧。
好,那接下来就看模版,我用的是ejs模版(/veiws/index.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title><%= title%></title> <% include includes/header %> <style type="text/css"> </style> </head> <body> <% include includes/page_header %> <div id="main"> <% include includes/nav %> <% include includes/inform_href %> <% include includes/dialog %> </div><!-- main end --> <div id="footer"></div> <% include includes/model_login_register %> </body> </html>
代码解释:
html部分都看得懂就不说了,其中出现的<%%>语法就是ejs模版的语法了,include命令明显是包含的意思,意思是包含includes/page_header(假如包含的文件后缀不是ejs则须要把后缀也加上)这个文件到这里来,看下个人目录结构:
而header.ejs文件内容为:
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="/css/css.css"> <script type="text/javascript" src="/js/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="/js/bootstrap.min.js"></script>
这个文件没用到ejs的语法,只是纯粹的把须要的css和js文件包含进来而已。
那么,再看page_header.ejs(代码比较乱,请直接砍<%%>部分)
<div id="header"> <h1>会议系统</h1> <span class='person'> <span id="hasLogin" class='person_panel <%if(user){%>hasLogin<%}%>'> 欢迎你,<a class="user" href="#" title="我的中心"><%if(user){%><%= user.username%><%}%></a> <span class="label label-primary logout_btn"style="cursor:pointer;">注销</span> </span> <span id="notLogin" class='person_panel <%if(!user){%>notLogin<%}%>'> 欢迎你,<span class="user">游客</span> <span class="label label-primary login_btn" data-toggle="modal" data-target="#loginModal" data-backdrop="static" style="cursor:pointer;">登录</span> <span class="label label-primary register_btn" data-toggle="modal" data-target="#registerModal" data-backdrop="static" style="cursor:pointer;">注册</span> </span> </span> </div> <script type="text/javascript"> $('.logout_btn').on('click',function () { console.log("点击了注销按钮"); $.ajax({ type: "POST", url: "/logout", data: {}, success: function(msg){ if (msg.state == "success") { $("#hasLogin").removeClass("hasLogin"); $("#notLogin").addClass("notLogin"); alert("注销成功!"); } } }); }) $('.login_btn').on('click',function () { $("#username").focus(); console.log("点击了登录按钮"); }) </script>
好比:<%if(user){%><%= user.username%><%}%>,这里<%%>里面能够写js代码,由ejs模版引擎解析,<%= XXX%>用来输出数据,而数据就是刚才从路由分发那里的res.render(模版文件名,数据)中传过来的。(我的以为ejs模版和jsp语法差很少,因此选择ejs,固然你也可选择jade等其余模版引擎)。
至此,整个流程基本跑通,须要实现其余高级的功能都在这个基础上实现。
其余知识点总结:
获取参数值的几种方式和区别
req.param(),具有了req.body,req.query,req.params的功能,惋惜express4.0开始弃用了,就很少说了。
req.params用法以下
app.get('/user/:name', function(req, res){ //:name的地方甚至能够用正则,获取就用req.params[0],假如是"/user",则param的值为{} var param = req.params.name; res.send('hello world' + param); });
req.body用法以下(主要是结合body-parser中间件处理post请求)
var express = require('express'); var bodyParser = require('body-parser'); //express4.0之后已经从express中分离出来 var app = express(); app.use(bodyParser()); app.use(bodyParser.json()); app.get('/user', function(req, res){ //假如提交的ajax post请求数据为:{name:"zhangsan"},假如是表单提交,这name的值为name="name"的值 var name = req.body.name; //name的值为"zhangsan" res.send('hello world' + name); });
req.query用法以下(主要是处理get请求)
app.get('/user', function(req, res){ //假如请求url为:/user?name="zhangsan",不管是ajax方式仍是url访问方式都同样的,只要是get方式的请求。 var name = req.query.name; //zhangsan res.send('hello world' + name); });