Express

Express

什麼是 Express ?

  1. Express 是一個基於 Node.js 封裝的上層服務框架,它提供了更簡潔的 API, 更實用的新功能
  2. Express通過中間件和路由讓程序的組織管理變的更加容
  3. Express提供了豐富的 HTTP 工具, 它讓動態視圖的渲染變的更加容易, 此外, 還定義了一組可拓展標準
  4. Express是目前最流行的node.js後端框架之一, 相當於jQuery和js之間的關係
  5. Express 不對 Node.js 已有的特性進行二次抽象,我們只是在它之上擴展了 Web 應用所需的基本功能
  6. 功能類似的後端框架:Koa.js, egg.js

爲什麼要使用Express?

  1. nodejs提供了的方法處理起來比較麻煩,在使用nodejs時有很多現成的框架幫助開發人員,其中最簡單的一個server框架就是Express
  2. 兩種使用方式
    ① 在項目文件夾中安裝express
    ② 通過express的generator來生成一個express的骨架

安裝express

  1. 進入應用目錄
  2. npm init 命令爲你的應用創建一個 package.json 文件
  3. 安裝 Express 並將其保存到依賴列表中
    npm install express --save
  4. 如果只是臨時安裝 Express,不想將它添加到依賴列表中,只需略去 --save 參數即可
    npm install express
  5. Express 應用生成器
    通過應用生成器工具 express 可以快速創建一個應用的骨架。
    ① 安裝
    npm install express-generator -g
    ② 常用操作
    express -h
    -h 選項可以列出所有可用的命令行選項
    安裝所有依賴包
    npm install
    ③ 設置視圖模板
    express --view=ejs demo1
    ④ 啓動應用
    MacOS 或 Linux 平臺
    DEBUG=myapp npm start
    Windows 平臺
    set DEBUG=myapp & npm start
    在瀏覽器中打開 http://localhost:3000/ 網址就可以看到這個應用了
    ⑤ 通過 Express 應用生成器創建的應用一般都有如下目錄結構

中間件

中間件是如何工作的?

  1. 原生Node中, http請求/響應處理都在一個函數中
    ① 代碼

    let  requestHandler = (request, response)  => {
        console.log("In comes a request to: " + request.url);
        response.end("Hello, world!");
    }
    

    ② 圖示
    在這裏插入圖片描述
    注意
    這並不是說在處理過程中不能調用其它函數,而是所有的請求響應都由該函數發送

  2. 中間件則使用一組中間件棧函數來處理這些請求
    ① 圖示
    在這裏插入圖片描述
    ② 作用
    用來處理 http 請求的一個具體的環節(可能要執行某個具體的處理函數)
    中間件一般都是通過修改 req 或者 res 對象來爲後續的處理提供便利的使用
    ③ 注意
    任何請求進來都會執行對應的處理函數
    不關心當前請求的具體請求方法和請求路徑

中間件分類?

use(‘請求路徑’, (req, res, next)=>{})
get(‘請求路徑’, (req, res, next)=>{})
post(‘請求路徑’, function (req, res, next) {})

第三方中間件類庫

  1. MORGAN:日誌記錄中間件
    1. 安裝
      npm install morgan --save
    2. Express 的靜態文件中間件

實操

  1. 在 http 中,沒有請求就沒有響應,服務端不可能主動給客戶端返回響應,就是一問一答的形式
  2. 對於一次請求來說,只能響應一次,如果發送了多次響應,則只有第一次生效
    next()是執行下一個路由
    // 1. 引入
    const express = require('express');
    const fs = require('fs');
    const path = require('path');
    
    // 2. 創建web服務器
    const app = express();
    
    // 4. 寫日誌
    app.use((req, res, next)=>{
        const log = `
          ----------------------------------------
          1) 請求的方式: ${req.method}, \n
          2) 請求的路徑: ${req.url}, \n
          3) 請求的時間: ${new Date()}, \n
          ----------------------------------------
        `;
        //  寫入文件
        fs.appendFile(path.join(__dirname, 'req.log'), log, (err)=>{
            if(err) throw err;
            next();
        });
    });
    
    // 加入很多很多中間件
    app.use((req, res, next)=>{
        console.log('1111111');
        next();
    });
    
    app.use((req, res, next)=>{
        console.log('2222222');
        next();
    });
    
    app.use((req, res, next)=>{
        console.log('333333');
        next();
    });
    
    
    app.get('/', (req, res, next)=>{
        res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
        res.write('<h2>Hello, World!</h2>');
        next();
    });
    
    app.get('/', (req, res)=>{
        res.write('<h2>您好,撩課學院!</h2>');
        res.end();
    });
    
    
    
    // 3. 開啓監聽
    app.listen(3000, ()=>{
        console.log('服務器已經啓動!');
    });
    

Express重點操作

  1. Hello World

    // 1. 引入
    const express = require('express');
    
    // 2. 調用 express() 方法,得到一個 app 實例接口對象
    //(類似於 http.createServer 得到的 server 實例)
    const app = express();
    
    // 3. 通過 app 根據路徑處理 get 和 post 請求
    app.get('/', (req, res)=>{
        res.write('<h1>hello</h1>');
        res.end()
    });
    
    app.get('/itlike', (req, res)=>{
        res.end('<h1>hello, itLike</h1>')
    });
    
    // 4. 開啓監聽,啓動服務器
    app.listen(3000, () => {
        console.log('服務已經啓動!')
    });
    
  2. 靜態資源文件
    app.use('/public', express.static('開放目錄的路徑'))
    在 use 方法中,如果指定了第一個路徑參數,則通過 req.path 獲取到的是不包含該請求路徑的字符串
    例如當前請求路徑是 /public/test.jpg, 則通過 req.path 拿到的就是 test.jpg
    使用

    app.use('/static', express.static(path.join(__dirname, 'static')));
    
  3. 錯誤/異常統一處理

Express 使用模板引擎

const express = require('express');
const path = require('path');
const app = express();

// 註冊模板引擎
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.get('/', (req, res)=>{
    const dataJson = {
        "lists":[
            {"title": "撩課學院1週年慶倒計時", "count": 675593, "up": 1},
            {"title": "女演員全美善自殺", "count": 634434, "up": 1},
            {"title": "哈登騎電動車被抓", "count": 623323, "up": 0},
            {"title": "吃酸辣粉被罰款", "count": 546767, "up": 0},
            {"title": "蔚來汽車莊莉離職", "count": 536237, "up": 1},
            {"title": "父母抓鬮陪女兒", "count": 525193, "up": 0},
            {"title": "宋仲基爸爸短信", "count": 475593, "up": 0},
            {"title": "宋仲基爸爸短信", "count": 375593, "up": 1},
            {"title": "今天天氣很好", "count": 275593, "up": 1}
        ],
        "source": "撩課風雲榜 - itLike.com"
    };
    res.render('list', dataJson);
});

app.listen(3000, ()=>{
    console.log('服務器已經啓動');
});

統一的錯誤處理日誌中間件

app.use((err, req, res, next)=>{
    const error_log = `
    =====================================
    錯誤名: ${err.name}, \n
    錯誤信息:${err.message}, \n
    錯誤時間:${new Date()}, \n
    錯誤堆棧:${err.stack}, \n
    =====================================
    `;
    fs.appendFile(path.join(__dirname, 'error.log'), error_log, (err)=>{
        res.writeHead(500, {'Content-Type': 'text/html;charset=utf-8'});
        res.end('500 服務器內部錯誤!')
    });
});

Express 應用生成器(腳手架)

通過應用生成器工具 express 可以快速創建一個應用的骨架。

安裝

npm install express-generator -g
-g全局安裝

常用操作

express -h
-h 選項可以列出所有可用的命令行選項
安裝所有依賴包
npm install

設置視圖模板

express demo1 --view=ejs

啓動應用

MacOS 或 Linux 平臺
DEBUG=myapp npm start
Windows 平臺
set DEBUG=myapp & npm start
在瀏覽器中打開 http://localhost:3000/ 網址就可以看到這個應用了

通過 Express 應用生成器創建的應用一般都有如下目錄結構

在這裏插入圖片描述
在這裏插入圖片描述
app.js

// 1.引入所有的包依賴文件
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');

// 2. 引入路由文件
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');

// 3. 創建web服務器
const app = express();

// 4. 設置模板引擎
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// 5. 使用各種中間件
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 6. 配置路由
app.use('/', indexRouter);
app.use('/users', usersRouter);

// 處理找不到頁面
app.use(function(req, res, next) {
  next(createError(404));
});

// 統一處理錯誤
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

7) socket.io

socket.io 是什麼?

  1. Socket.io 將 Websocket 和輪詢( Polling )機制以及其它的實時通信方式封裝成了通用的接口,並且在服務端實現了這些實時機制的相應代碼。
  2. H5 的新技術 Websocket 僅僅是 Socket.io 實現實時通信的一個子集。

如何使用socket.io?

  1. 安裝
    npm install socket.io --save
    進入 package.json 所在的目錄下, 運行上面命令
  2. 引入
    // 引入包
    let socketPackage = require('socket.io');
    // 針對 http server 生成 socket.IO 實例對象
    let io = socketPackage(server);
    使用 socket.IO 的時候,需要生成一個 實例對象;
    生成這個實例對象的依賴原生 node 已經建立好的 httpServer 對象

常用API?

服務器端

  1. 監聽連接

    io.on('connection',function(socket));
    

    當有客戶端向本服務器建立連接的時候, ‘connection’ 事件就被激發。對應的回調函數就會執行。回調函數的參數 socket 就是這個客戶端與服務器的 連接對象

  2. 給所有客戶端廣播消息

    io.sockets.emit('String',data);
    

    服務器主動向客戶端發送消息, 消息的事件名爲 myEvnetLabel , 消息的具體內容爲 data

  3. 給指定的客戶端廣播消息

    io.sockets.socket(socketid).emit('String', data);
    
  4. 監聽客戶端消息

    socket.on(‘myEvnetLabel’,function(data){});
    

    當某個客戶端向服務器發送消息的時候,服務器監聽這個消息,並將其回調函數執行

瀏覽器端

  1. 開啓連接

    let url = 'http://localhost:3000';
    let socket = io.connect(url);
    
  2. 監聽服務器的消息

    socket.on('myEvnetLabel',function(data){});
    

    當服務器有消息到達的時候,回調函數會被激發

    1. 向服務器發送消息
    socket.emit(‘myEvnetLabel’, data);
    

    客戶端主動向服務器發送消息, 消息的事件名爲 myEvnetLabel , 消息的具體內容爲 data

客戶端socket.on()監聽的事件

connect:連接成功
connecting:正在連接
disconnect:斷開連接
connect_failed:連接失敗
error:錯誤發生,並且無法被其他事件類型所處理
message:同服務器端message事件
anything:同服務器端anything事件
reconnect_failed:重連失敗
reconnect:成功重連
reconnecting:正在重連
當第一次連接時,事件觸發順序爲:connecting->connect;當失去連接時,事件觸發順序爲:disconnect->reconnecting(可能進行多次)->connecting->reconnect->connect。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章