Node初步實踐

魯鵬發表於2016-03-24

初步嘗試一步一步建立Web世界。

初步嘗試Express&jade快速建站

最近一直在看Web開發相關的書籍,一週時間讀完了《Node開發指南》一書,由於之前瞭解過一些Node的相關知識,於是前面基礎知識學得比較快,到開發實踐這一章的時候,卻發現好多內容不能跟著練習了。因為近幾年Node的發展過於快速,其Web開發框架Express必然也更新得比較頻繁,並且版本與版本之間差異較大。所以,書中必然有好多程式碼在現在來看肯定執行不了,但是大體的框架還是在那裡,想動手實踐還是得對照著官方文件進行。

1. 生成Express專案

根據官方文件入門的介紹,根據Express建站的步驟大致寫一下:

  1. npm install express 安裝express
  2. npm install express-generator -g 安裝express應用生成器
  3. express myapp 生成express專案目錄以及基本啟動程式碼
  4. DEBUG=myapp npm start 啟動應用(Mac or Linux);set DEBUG=myapp & npm start 啟動應用(Windows)
  5. 瀏覽器訪問http://localhost:3000

通過上面幾步很快就完成了一個專案的部署,那麼接下來就是要往裡填寫內容了,用框架開發就是這麼快,但是會忽略掉很多重要的細節。

開啟myapp資料夾,會看到該專案的目錄結構如下:

.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.jade
    ├── index.jade
    └── layout.jade

瞭解過一些Node的相關知識就知道,Node是通過動態網頁的方式來實現網站的,就如同其他語言Java、PHP一樣,要實現動態頁面就要在HTML模板中插入程式程式碼,於是就有了JSP、PHP以及ASP等技術。通過JavaScript實現的模板引擎有很多,Jade就是其中之一,為什麼選擇它,因為Express預設就是它,反正也是新接觸,那就它咯。

2. Jade模板引擎

由於新學,也沒有什麼經驗可談,基本用法參考官網就可以了。這類語言基本上看一遍就百分之八九十了,接下來就是熟練使用它。

3. 回頭看看app.js

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

這裡就是設定Jade模板引擎以及檢視目錄的地方。

4. 編寫路由規則

編寫路由規則,開啟routes/index.js檔案,新增4條路由規則,代表4個不同的頁面。

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Home Page'});
});

/* GET detail page. */
router.get('/detail/:id', function(req, res, next) {
  res.render('detail', { title: 'Detail Page'});
});

/* GET admin page. */
router.get('/admin', function(req, res, next) {
  res.render('admin', { title: 'Admin Page'});
});

/* GET list page. */
router.get('/list', function(req, res, next) {
  res.render('list', { title: 'List Page'});
});

5. 瞧瞧jade模板檢視檔案

開啟views/layout.jade

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

看了一遍jade語法的基本就能看出這是一個基本頁面,然後再開啟views/index.jade

extends layout
block content
  h1= title
  p Welcome to #{title}

路由規則中,title變數就用與此處,如此即為動態頁面。npm start啟動應用,訪問http://localhost:3000得到頁面如下圖。

6. 依次建立detaillistadmin頁面

根據路由規則所規定的訪問路徑,依次訪問,會得到不同的動態頁面。

轉載儲存:建站 | LP's Blog

初步使用bootstrap快速建立頁面

初步嘗試使用Express搭建了一個Web框架,那麼接下來就是要在該框架下寫上自己的頁面,快速建立頁面這裡選擇了bootstrap前端框架,通過它即使你不太懂前端設計,寫出來的頁面也不會太難看。

1. 安裝bower前端包管理器

bower是一個前端軟體包管理器,便於安裝、更新以及解除安裝javascript,css,html等框架資源,並解決之間的相互依賴關係。

npm install -g bower   // 安裝
bower help   // 檢視幫助

這裡YY一下:

npm是node.js的包管理器,通過它安裝了expressexpress-generatorsupervisorbower等等軟體,bower又是前端框架的軟體包,安裝了bootstrap以及jquery等一些依賴包。突然發現簡直是包包相扣啊,漸漸的醉了。其中的水實在是太深了,想簡單學個web開發也不是那麼容易的事啊,有種淡淡的憂傷。然並卵,心嚮往之,一如既往。

2. 安裝bootstrap以及jquery

當然你也可以直接將bootstrap以及jquery下載下來,放入專案文件中,不用安裝什麼包管理器,自己解決簡單的依賴關係就OK了,但是不都是為了快速建站嘛,裝個包管理器自動解決依賴關係。並且在釋出自己的專案的時候,也不需要將所有的框架包一塊釋出,而只需將相關的json檔案放到專案裡就可以了,別人一目瞭然你的依賴關係,便於快速搭建。

有了bower,直接bower install bootstrap就OK了,因為依賴關係,它會自動給你裝上jquery,完事。

3. 模板引擎中引入bootstrap以及jquery

安裝好了或者說專案中已經放置好了bootstrapjquery之後,接下來就是在檔案中引用它,在views資料夾中建立一個head.jade檔案,顧名思義就是放置HTML中head標籤裡面的一些內容。如下程式碼:

link(href='/bootstrap/dist/css/bootstrap.min.css',rel='stylesheet')
script(src='/jquery/dist/jquery.min.js')
script(src='/bootstrap/dist/js/bootstrap.min.js')

建立完head.jade後,接下來在所有需要的頁面中,加上include head.jade包含到頁面中就OK了。

4. 使用模版佈局

由於基本上所有的頁面都需要包含head.jade,總不能每個頁面都寫上include head.jade 吧,於是佈局文件layout.jade就要起作用了。單獨建立layout.jade檔案,將一些共性的程式碼寫進去。

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    include ./includes/head
  body
    include ./includes/header
    h1= title
    block content

如上,一些獨立的模組依然可以通過include語句進行載入,最後一句block content就是模版佈局的關鍵,意思就是在模版的此處插入頁面,也就是應用此模版佈局的差異處。

然後在應用此模版佈局的頁面中,加上extent layout就OK了。如下:

extends ../layout
block content
  p Welcome to #{title}

注意:extends模版檔案以及include程式碼中使用檔案儘量使用相對路徑。

5. 開始編輯頁面

準備工作都做得差不多了,那麼接下來就是使用jade語法以及bootstrap樣式來編輯頁面了。下面簡單大致寫個首頁(index)以及詳情頁(detail)。

// index.jade
extends ../layout

block content
  .container
    .row
      h1= title
        small 圖書列表
      each item in books
        .col-md-3.col-xm-6
          .thumbnail.text-center
            a(href='/books/#{item._id}')
              img(src='#{item.poster}',alt='#{item.title}')
            .caption
              h3= item.title
              .btn-group
                a.btn.btn-primary(href='/books/#{item._id}') 檢視詳情
                a.btn.btn-primary(href='#{item.buyUrl}') 購買書籍

// detail.jade
extends ../layout

block content
  .container
    .row
      h1= title
        small= book_title
      .col-md-9.col-sm-9
        .thumbnail
          img(src='#{book_poster}')
          .caption
            p= book_info
            a.btn.btn-primary(href='#{book_buyUrl}') 購買書籍
      .col-md-3.col-sm-3
        h3 作者
        p #{book_author}
        h3 出版年月
        p #{book_year}年
        h3 頁數
        p #{book_pages}頁
        h3 定價
        p ¥#{book_price}

上面兩個頁面是bootstrap裡最基本的佈局,想詳細學習bootstrap推薦Bootstrap 教程 | 菜鳥教程

建站 | LP's Blog

初步使用Node連線Mysql資料庫

使用Node做Web頁面開發,基本上是連線非關係型資料庫mongodb,而這裡我還是先嚐試連線了一下mysql資料庫,因為相對於mysql來說mongodb過於生疏,想著快速出來頁面,所以選擇相對熟悉一些的mysql

1. 安裝mysql

下載MySQL :: MySQL Downloads,並進行安裝。安裝完,會引導你對資料庫進行配置,設定root密碼以及建立普通使用者以及密碼。

2. 安裝Node-mysql

通過npm安裝mysql的軟體包,通過它方便快速呼叫函式連線mysql資料庫。進入專案資料夾,執行npm install mysql --save就行了。

安裝完,在專案資料夾的node_modules目錄下會生成mysql的目錄。

3. 檢視readme文件

進入mysql目錄中,檢視README文件,這步很重要,不要到處百度Google搜尋怎麼用,因為由於版本的不一樣,也許你得到的答案並不能使你成功連線資料庫。畢竟Node發展如此之快。

如果你認真讀了README文件,接下來的步驟就不用再看了,避免由於版本不一致而誤導你。

4. 連線mysql資料庫

進入專案文件,新建TestMysql.js示例,編寫如下程式碼:

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret',
  database : 'my_db'
});

connection.connect();

connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
  if (err) throw err;

  console.log('The solution is: ', rows[0].solution);
});

connection.end();
  • 連線基本引數

    • host 主機名,localhost代表本地
    • user Mysql使用者
    • password 密碼
    • database 連線的資料庫
  • client.connect()連線資料庫

  • client.query()執行SQL語句
  • client.end()關閉連線。

然後通過node TestMysql.js執行程式,確保你在執行之前已經啟動了Mysql服務。

5. 增刪改查

使用資料庫無外乎增刪改查,下面示例可能會對你有些幫助。

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret',
  database : 'my_db'
});

connection.connect();

// 增加記錄
client.query('insert into test (username ,password) values ("lupeng" , "123456")');

// 刪除記錄
client.query('delete from test where username = "lupeng"');

// 修改記錄
client.query('update test set username = "pengloo53" where username = "lupeng"');

// 查詢記錄
client.query("select * from test" , function selectTable(err, rows, fields){
  if (err){
    throw err;
  }
  if (rows){
    for(var i = 0 ; i < rows.length ; i++){
      console.log("%d\t%s\t%s", rows[i].id,rows[i].username,rows[i].password);
    }
  }
});

connection.end();

到此,Mysql資料庫的初步連線就告一段落了,接下來就可以在Node專案中自行發揮了。

轉載儲存:建站 | LP's Blog

初步使用Express+Mysql非同步讀取資料展示頁面

通過之前3步的初步學習,學會了如何使用jade模版編寫動態頁面,同時也學會了如何使用mysql資料庫。今天實現一個簡單的例子,結合expressmysql,從資料庫中取出資料,最後在前臺頁面展示出來。 下面進入正題,通過Express+Mysql實現非同步讀取資料並展示在頁面中,分為下面幾步:

1. 建立資料訪問物件檔案

也就是常說的DAO(data access object),在專案目錄中,新建db資料夾,放訪問資料庫的相關檔案,在db目錄中新建db.js,其中程式碼如下:

var mysql = require('mysql');

var options = {
  host: 'localhost',
  user: 'lupeng',
  password: '080910',
  database: 'myapp'
}

exports.createConn = function (){
  var client = mysql.createConnection(options);
  return client;
}

exports.getUsers = function (client,callback){
  var selectstatement = 'select * from user';
  client.query(selectstatement, function(errs,rows,fields){
      if (errs){
        callback(errs);
      }
      if (rows){
        console.log(rows);
        callback(rows);
    }
  });  
}

基本上是標準的一套程式碼,連線資料庫方法,查詢資料方法,當然實現更復雜的功能,會利用到資料池以及更多SQL。

上述程式碼簡單實現了兩個方法,一個是獲取資料庫物件createConn,一個是獲取使用者的方法getUsers注意得到資料庫資料後,作為引數賦予回撥函式callback。

2. 編輯路由方法

當訪問到某個路徑的時候,查詢資料庫,並返回結果,最終通過res物件將內容傳送到客戶端上。app.js中編寫路由方法如下:

var db = require('../db.js');
// ... 省略
app.get('/',function(req,res){
  var client = db.createConn();
  db.getUsers(client,function(results){
    if(results){
      res.render('index',{results: results});
    }
  });
});

首先呼叫createConn方法獲取資料庫物件client,然後呼叫getUsers方法取得資料,實現回撥函式,將資料回傳回來,最後通過res物件傳送至前臺頁面。

3. view模版

res物件渲染index頁面,最終顯示在前端。這裡使用的是jade模版引擎,下面看看index.jade示例程式碼:

doctype html
html
  head
    title= title
    link(href='/bootstrap.min.css',rel='stylesheet')
  body
    .container
      .row
        h1 讀取使用者資料庫
          small Mysql
        .table-responsive
            table.table
              thead
                tr
                  th ID
                  th 使用者名稱
                  th 密碼
                tbody
                  each item in results
                    tr
                      td= item.id
                      td= item.username
                      td= item.password

前臺顯示如下圖,一個列印了資料庫資料的簡單頁面。

當然前提要在資料庫中新建一個myapp的資料庫,在myapp中新建user表。

總結

  1. 非同步讀取資料庫內容後,將資料作為引數賦予回撥函式;
  2. 路由模組中通過實現回撥函式獲取資料庫資料,最終顯示在前臺頁面;

轉載儲存:建站 | LP's Blog

Node實現todo-list來理解HTTP的方法

在Web程式設計中,最常用的HTTP方法有GET,POST,DELETE,PUT,這些標準的HTTP方法構成了WEB應用程式中一套基本的RESTful原則。

這裡通過Node最簡單HTTP模組來實現一個完整的todo-list命令列程式,也就是常說的CLI(command-line interface),通過它瞭解一下HTTP中最基本的方法。

伺服器與客戶端的互動不通過瀏覽器實現,而通過最純粹的命令列工具curl來實現,使其方法更加透明而便於理解。減少中間寫HTML程式碼的環節。

cURL - Download從這個介面下載,*nix系統基本上都自帶有,Windows使用者需要下載該命令列工具。

接觸Node首先就是使用HTTP模組寫出列印Hello,world的伺服器,這才是真正意義上Node的Hello,world,程式碼如下:

var http = require('http');
http.createServer(function (req,res){
  res.writeHead(200 , {"Content-Type" : "text/html"});
  res.end('Hello,world');
}).listen(9000);
console.log("Your server is started @ http://localhost:9000");

使用瀏覽器訪問http://localhost:9000就可以列印出Hello,world

下面todo-list的例子,通過對req.method請求方法的判斷,對伺服器發起HTTP的POSTDELETEGET等基本方法。程式碼如下:

var http = require('http');
var url = require('url')
var items = [];
http.createServer(function(req,res) {
  switch (req.method){
    case 'POST':
      var item = '';
      req.setEncoding('utf8');
      req.on('data', function(chunk){
        item += chunk;
      });
      req.on('end',function(){
        items.push(item);
        res.end('add success!\n','utf8');
      });
      break;
    case 'GET':
      for (var i =0 ; i < items.length ; i ++){
        res.write(i + ') ' + items[i] + '\n','utf8');
      }
      res.end();
      break;
    case 'DELETE':
      var pathname = url.parse(req.url).pathname;
      var i = parseInt(pathname.slice(1) , 10);
      if (isNaN(i)){
        res.statusCode = 400;
        res.end('Invalid item id!\n');
      }else if (!items[i]){
        res.statusCode = 404;
        res.end('Item not found!\n');
      }else{
        items.splice(i , 1);
        res.end('delete success!\n');
      }
      break;
  }
}).listen(9000);
console.log('Your server is started @9000');

上面程式碼顯示了POST請求的處理方法,以及Delete Item的時候,對防錯的一些處理方法。對程式的健壯性有一定的保障。當然功能上還是非常弱的。

將上面程式碼儲存為app.js,啟動伺服器:node app.js

  • 輸入curl -d "read book" http://localhost:9000發起POST請求,新增一條item;
  • 輸入curl http://localhost:9000發起GET請求,獲取item列表;
  • 輸入curl -X DELETE http://localhost:9000/0刪除第0條item。

OK了,自己嘗試一下吧。

Node實現最簡單的todo-list頁面

上一篇是通過curl命令列工具實現的一個簡單的todo-list CLI程式,但是沒有頁面總歸是不夠自然,這裡就新增上簡單的HTML頁面,然後同樣實現那個簡單的todo-list功能頁面。通過瀏覽器來感受一下Node Web的魅力。

var http = require('http');
var qs = require('querystring');
var items = [];

var server = http.createServer(function(req,res){
  if('/' == req.url){
    switch(req.method){
      case 'GET':
        show(res);
        break;
      case 'POST':
        add(req,res);
        break;
      default:
        badReq(res);
    }
  }else{
    noFound(res);
  }
});

新增一個req.url訪問路徑的限制,然後指定GET請求以及POST請求對應的方法。當伺服器接收到GET請求時,執行show()方法;當伺服器收到POST請求時,執行add()方法。同時為了程式的健壯性,填加了相關錯誤處理的方法,分別為響應失敗以及404 Not Found處理方法。

下面主要實現show()方法以及add()方法就行了。

function add(req,res){
  var body = '';
  req.on('data',function (chunk) {
    body += chunk;
  });
  req.on('end',function(){
    var list = qs.parse(body);
    items.push(list.name);
    show(res);
  });
}

先看下add()方法,因為不涉及到頁面,所以此處程式碼基本沒有什麼變化,只是在新增完成後,直接執行show()方法顯示出來。下面再來看看show()方法。

function show(res){
  var item = '';
  var pageContent1 = '<html><head><title>Todo List</title></head><body>'
    + '<h1> Todo List </h1>'
    + '<ol>';
  var pageContent2 = '';
  for (var i = 0; i < items.length; i++) {
    pageContent2 += '<li>' + items[i] + '</li>';
  };
  var pageContent3 = '</ol>'
    + '<form method="POST" action="/">'
    + '<input type="text" name="name"><br/>'
    + '<input type="submit" value="add a list"><br/>'
    + '</form>';
  var pageContent = pageContent1 + pageContent2 + pageContent3;
  res.setHeader("content-type","text/html");
  res.end(pageContent);
}

最原始的顯示頁面的方法,將HTML程式碼直接寫進邏輯中,雖然不建議這麼幹,但是還有比這更直觀的嗎?將HTML直接通過res物件返回到客戶端。

當然還有兩個方法badReq()noFound(),實現如下:

function badReq(res){
  res.statusCode = 500;
  res.end('Bad Request!');
}
function noFound(res){
  res.statusCode = 404;
  res.end('Not Found!');
}

OK了,儲存檔案為app.js,然後node app.js啟動它,在瀏覽器中輸入http://localhost:9000看下效果吧。通常情況下,瀏覽器只傳送GETPOST請求,想實現刪除的功能,可以藉助URL來實現或者通過Ajax都是可行的。這裡給出了通過URL來實現的方法,想要刪除第一條,使用http://localhost:9000/del/1試試。

相關文章