【重點突破】——使用Express建立一個web服務器

1、引言css

在自學node.js的過程當中有一個很是重要的框架,那就是Express。它是一個基於NodeJs http模塊而編寫的高層模塊,彌補http模塊的繁瑣和不方便,可以快速開發http服務器。這裏,就要用Express建立一個Web服務器,用來深刻的理解這個框架,並熟悉建立Web服務器的過程。html

 

2、核心概念——中間件node

 

Express 是一個自身功能極簡,徹底是由路由和中間件構成一個的 web 開發框架:從本質上來講,一個 Express 應用就是在調用各類中間件。mysql

 

中間件(Middleware) 是一個函數,它能夠訪問請求對象(request object (req)), 響應對象(response object (res)), 和 web 應用中處於請求-響應循環流程中的中間件,通常被命名爲 next 的變量。jquery

 

中間件的功能包括:web

  • 執行任何代碼。
  • 修改請求和響應對象。

終結請求-響應循環。調用堆棧中的下一個中間件。ajax

若是當前中間件沒有終結請求-響應循環,則必須調用 next() 方法將控制權交給下一個中間件,不然請求就會掛起。sql

  

Express 應用可以使用以下幾種中間件:數據庫

  • 應用級中間件
  • 路由級中間件
  • 錯誤處理中間件
  • 內置中間件
  • 第三方中間件

使用可選則掛載路徑,可在應用級別或路由級別裝載中間件。另外,你還能夠同時裝在一系列中間件函數,從而在一個掛載點上建立一個子中間件棧。express

 

 

app.use(url,  (req, res, next)=>{ //.....中間件要執行的代碼 next( ); //調用下一個中間件或路由

 

3、模塊下載

由於建立Web服務器要用到第三方模塊的mysql和Express,因此須要在建立新項目以後,在NPM中進行下載,安裝這兩個模塊,具體過程以下:

  1. Webstorm建立新項目project,右鍵點擊project
  2. show in Explorer 進入目標文件夾 
  3. 按shift  同時點擊右鍵,在空白麪板處
  4. 在此處打開命令窗口
  5. >npm  i  mysql    等待下載
  6. >npm  i  express  等待下載

下載完成後,webstorm中新建立的project下會自動更新出一個node_modules目錄,裏面會有須要的mysql和Express。

 

4、引例說明

使用Express建立一個web服務器,能夠向客戶端提供一個 /index響應,內容是一個HTML頁面,其中還使用一個index.css文件/index.js文件

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="index.css"/>
</head>
<body>
   <h1>INDEX.HTML</h1>
   <script src="index.js"></script>
</body>
</html>
css文件和js文件此處省略
//app.js執行文件
const http = require('http'); const express = require('express'); var app = express(); http.createServer(app).listen(8080); app.get('/index',(req,res)=>{ res.sendFile(__dirname+'/pulic/index.html'); }); app.get('/index',(req,res)=>{ res.sendFile(__dirname+'/pulic/index.css'); }); app.get('/index',(req,res)=>{ res.sendFile(__dirname+'/pulic/index.js'); });

小坑:若是index.html室友路由引入的,即便裏面的index.css和index.js引入到了html中,若沒有經過路由引入到app.js文件中,則這兩個css與js文件是存在,但不響應的。因此,必須都經過路由引入到app.js文件中。可是,這一樣會有一個問題,那就是若是要引入的文件太多,又必需要一個不漏的引入,那這樣一個一個引太繁瑣了,工做量太大,這就是中間件的重要性了,使用中間件能夠方便快鍵的引入所需的全部文件。

 

Express 4.x官方還提供了一箇中間件函數:app.use(express.static('public'));//若客戶端請求了/public目錄下的某個資源,它能夠直接向客戶端返回,不會再調用後續的路由。

 

 

5、web服務器建立

要求:使用Express建立Web服務器應用,能夠接收以下的請求:

一、編寫SQL:建立數據庫dangdang,書籍信息表book(bid,title,price,pubDate-出版日期,into-內容簡介),並插入4行書籍記錄。

 

二、至少能夠向客戶端提供以下靜態資源:

/public/booklist.html      初始時顯示一個空白的表格,頁面加載完成後向服務器異步請求全部的書籍信息。

/public/jquery-1.11.3.js     在DIV中顯示某一本書的詳情

/public/book_detail.html  在DIV中顯示某一本書的詳情

/public/book_add.html   顯示一個添加書籍的表單,點擊「提交」按鈕,異步提交給服務器

/public/book_update.html  顯示一個修改書籍的表單,輸入域中是當前要修改的書籍信息,點擊「提交」按鈕,異步提交給服務器。

 

三、以及以下動態資源地址——注意:下述地址都使用Ajax異步請求

GET  /book  向客戶端輸出書籍表中的全部記錄,以JSON格式

GET /book/:id  向客戶端輸出指定編號的書籍所有信息,以JSON格式

DELETE  /book/:id  刪除指定編號的書籍記錄,向客戶端輸出{code:1,bid:xx}或者{code:2,msg:'指定書籍編號不存在'}

POST  /book 接收客戶端提交的請求主體數據(title/price/pubDate/intro),執行書籍添加操做保存入數據庫,向客戶端輸出{code:1,bid:xx}

PUT /book 接收客戶端提交的請求主體數據(bid/title/price/pubDate/intro),執行書籍更新操做修改數據庫中對應的書籍,向客戶端輸出{code:1,affectRows:1}

 

實現:

DROP DATABASE IF EXISTS dangdang; CREATE DATABASE dangdang CHARSET=UTF8; USE dangdang; CREATE TABLE book( bid INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(64), price DECIMAL(8,2), pubDate BIGINT, intro VARCHAR(2048) ); INSERT INTO book VALUES (NULL, '西遊記', '35.5', '1350123456789','描述了一個和尚和三個妖怪的故事'), (NULL, '水滸傳', '45.5', '1360123456789','描述了105個男人和3個女人的故事'), (NULL, '紅樓夢', '55.5', '1370123456789','描述了1個富二代的故事'), (NULL, '三國志', '65.5', '1380123456789','描述了羣雄爭霸的故事');
//book_list.html <!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>書籍列表</h1>
    <hr/>
    <table border="1" width="100%">
        <thead>
            <tr>
                <th>編號</th>
                <th>書名</th>
                <th>價格</th>
                <th>出版日期</th>
                <th>操做</th>
            </tr>
        </thead>
        <tbody>
             <td colspan="5">信息加載中....</td>
        </tbody>
    </table>

    <script src="js/jquery-1.11.3.js"></script>
    <script>
        //待當前頁面加載完成,異步請求全部書籍信息 GET /book
 $.ajax({ type:'GET', url:'/book', success:function(list){ //遍歷list數組,每一個obj拼接爲一個TR>TD*5,TBODY
               var html =''; for(var book of list){ html +=` <tr>
                      <td>${book.bid}</td>
                      <td>${book.title}</td>
                      <td>${book.price}</td>
                      <td>${book.pubDate}</td>
                      <td>
                         <a class="detail" href="#">詳情</a>
                         <a class="delete" href="#">刪除</a>
                         <a class="update" href="#">修改</a>
                      </td>
                    </tr>
 `; } $('tbody').html(html); } }); </script>
</body>
</html>
//book_detail.html <!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style> div { border-bottom: 1px solid #aaa; padding: 1em;
        }
    </style>
</head>
<body>
<h1>書籍詳情</h1>
<hr/>
<div id="bid">
    <b>書籍編號:</b>
    <p>xxx</p>
</div>
<div id="title">
    <b>書籍標題:</b>
    <p>xxx</p>
</div>
<div id="price">
    <b>單價:</b>
    <p>xxx</p>
</div>
<div id="pubDate">
    <b>出版日期:</b>
    <p>xxx</p>
</div>
<div id="intro">
    <b>內容簡介:</b>
    <p>xxx</p>
</div>

<script src="js/jquery-1.11.3.js"></script>
<script>
    //待頁面加載完成,異步請求指定編號的書籍詳情
    //console.log(location);
    //console.log(location.search);
    //console.log(location.search.split('='));
    var bid = location.search.split('=')[1]; $.ajax({ type: 'GET', url: '/book/'+bid, success: function(book){ console.log('成功接收到服務器返回的書籍信息'); console.log(book); $('#bid p').html(book.bid); $('#title p').html(book.title); $('#price p').html(''+book.price); var d = new Date(book.pubDate); $('#pubDate p').html(d); $('#intro p').html(book.intro); } }); </script>
</body>
</html>

//其他兩個html內容省略
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>更新書籍內容</h1>
    <hr/>

    <script src="js/jquery-1.11.3.js"></script>
</body>
</html>


<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>添加書籍</h1>
    <hr/>

    <script src="js/jquery-1.11.3.js"></script>
</body>
</html>
//執行程序app.js
const http = require('http'); const express = require('express'); const book = require('./book'); var app = express(); http.createServer(app).listen(8080); //使用中間件向客戶端返回靜態內容
app.use(express.static('public')); //定義路由,向客戶端返回動態內容
app.get('/book', book.getAll);//自建一個book模塊,調用getAll方法
app.get('/book/:bid', book.getById);
//自建book.js
const mysql = require('mysql'); //數據庫鏈接池
var pool = mysql.createPool({ user:'root', database:'dangdang', connectionLimit:5 }); module.exports = { getAll:(req, res)=>{ pool.getConnection((err,conn)=>{ conn.query('SELECT * FROM book',(err,result)=>{ //把查詢結果集轉換爲JSON字符串,輸出給客戶端
 res.json(result); conn.release();//釋放鏈接回鏈接池
 }) }) }, getById: (req, res)=>{ var bid = req.params.bid; console.log('客戶端想查詢的書籍編號:'+bid); //根據書籍編號,執行SQL語句,查詢出對應書籍的信息,以JSON格式發送給客戶端:{"bid":.., "title":...}
        pool.getConnection((err, conn)=>{ conn.query('SELECT * FROM book WHERE bid=?', [bid], (err, result)=>{ //console.log(result); //[ {} ]
                res.json(result[0]); //只須要向客戶端返回一個JSON對象便可,無需返回數組
 conn.release(); }) }) } };

 

效果:

 

 


 注:轉載請註明出處

相關文章
相關標籤/搜索