node開發web項目

第一步:安裝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>
      &nbsp;<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> &nbsp;
  	  <span class="label label-primary login_btn" data-toggle="modal" 
  	data-target="#loginModal" data-backdrop="static" style="cursor:pointer;">登錄</span>&nbsp;
  	  <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等其餘模版引擎)。

  • 至此,整個流程基本跑通,須要實現其餘高級的功能都在這個基礎上實現。


其餘知識點總結:

  1. 獲取參數值的幾種方式和區別

    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);
});
相關文章
相關標籤/搜索