Express框架的總體感知

Express是基於node.js平臺的快速、開放、極簡的web開放框架,它的地位與做用有點相似於前端的jquery框架。它的英文官網地址爲 http://expressjs.com,其對應的中文官網地址爲 http://www.expressjs.com.cn 。下面來簡單介紹這個框架的用法。html

1、下載及引包

express做爲一個第三方模塊包,一樣是經過npm的方式進行下載,在當前的項目文件夾下,用命令-> npm install express 來完成下載。再經過 const express = require('express'); 來完成引包。前端

2、express提供建立http服務器的功能

當使用了express這個模塊包以後,再也不須要引用nodehttp模塊,也能提供建立http服務器的功能。其基本的代碼段結構爲:node

const express = require('express');
var app = express();
app.get('/',(req,res)=>{
    res.send('');
});
app.listen(3000,'192.168.155.1');

引包以後返回一個函數體,將該函數體調用執行以後的返回值用app來接收。app相似於建立的那個http服務器實例,該服務器監聽IP地址爲192.168.155.1,端口號爲3000。當瀏覽器以get方式訪問http://192.168.155.1:3000/時,調用執行該回調函數。其中res.send()express內部封裝的方法,在其內部能夠直接寫入返回的字符串參數,不用再用res.writeHead()來設置狀態碼和mine類型。jquery

該回調函數內部雖然能夠直接使用express本身封裝的res.send()方法,不過原生的res.write()res.end()方法仍然可使用。這三種方法內部參數默認填寫字符串類型,若是爲其餘類型的變量,須要使用.toString()的方法先將其完成類型轉換。而且res.send()res.end()均只能出現一次。web

3、express提供強大的路由能力

上述代碼段當中的app.get('/',(req,res)=>{});即爲一條路由選擇,表示當客戶端以get方式訪問根目錄時,執行該回調函數當中的代碼。咱們能夠以這種方式進行路由選擇的設計,客戶端訪問服務器能夠有多種方式,如getpostadddelete等,不過網頁端訪問通常只有getpost這兩種方式,其餘的方式通常由app端發起。在瀏覽器端輸入網址、回車、刷新等方式均是默認以get方式進行訪問。使用app.all()方法則表明處理這個路由下的任何method請求。express

一、使用冒號語法提取客戶端訪問的url當中的數據

示例代碼段爲:npm

const express = require('express');
var app = express();
app.get('/:name/:age',(req,res)=>{
    var a = req.params.name;
    var b = req.params.age;
    console.log(a);
    console.log(b);
    res.send();
});
app.listen(3000,'192.168.155.1');

則客戶端在訪問以後的返回結果爲:瀏覽器

圖片描述

二、在路由設計時,url地址當中不區分字母的大小寫

以下所示的示例代碼:服務器

const express = require('express');
var app = express();
app.get('/ABb',(req,res)=>{
   res.send('成功返回!')
});
app.listen(3000,'192.168.155.1');

此時客戶端以get方式訪問該網址時,不區分字母大小寫。app

圖片描述

三、在作路由處理時,用戶輸入的url地址當中全部get方式提交的參數及錨點均會被忽略

以下所示的示例代碼:

const express = require('express');
var app = express();
app.get('/a',(req,res)=>{
   res.send('成功返回!')
});
app.listen(3000,'192.168.155.1');

此時客戶端訪問爲http://192.168.155.1:3000/a#?name=qianqian&age=24時,一樣與上述這條路由相匹配,執行其內部的回調函數。

圖片描述

四、express當中全部路由中間件的書寫順序相當重要

當有客戶端訪問該服務器時,會根據用戶輸入的網址與咱們的路由設計的代碼進行路由匹配,一旦找到一個匹配的路由中間件以後,則執行其內部的回調函數,以後再也不與後面代碼當中出現的路由中間件進行路由匹配。以下所示的示例代碼:

const express = require('express');
var app = express();
app.get('/:username/:method',(req,res)=>{
   console.log(1);
   res.end();
});
app.get('/admin/login',(req,res)=>{
    console.log(2);
    res.end();
})
app.listen(3000,'192.168.155.1');

此時當客戶端訪問http://192.168.155.1:3000/admin/login時,因爲先匹配上了第一個路由,執行內部的回調函數,再也不匹配第二個路由。

圖片描述

若是想讓其匹配上多條路由,則在上述的可能匹配上的路由的回調函數當中加入參數next,並在回調函數體的最後加上next();便可。示例代碼以下所示:

const express = require('express');
var app = express();
app.get('/:username/:method',(req,res,next)=>{
   console.log(1);
   next();
});
app.get('/admin/login',(req,res)=>{
    console.log(2);
    res.end();
})
app.listen(3000,'192.168.155.1');

此時當客戶端訪問http://192.168.155.1:3000/admin/login時,因爲先匹配上了第一個路由,執行內部的回調函數,接下去再匹配第二個路由,而後執行其回調函數。

圖片描述

因爲express當中全部路由中間件的書寫順序相當重要,因此咱們在設計路由時,通常把具體的路由寫在上面,把抽象的路由寫在下面。

五、app.use()是一個特殊的路由中間件

咱們使用app.get()app.post()等路由中間件進行路由設計時,咱們都是須要對客戶端輸入的網址進行精確的路由匹配的(最多隻能作到忽略url當中的錨點即get方式提交的參數數據)。但用app.use()來進行路由設計時,咱們能夠把第一個參數的層級無限擴充下去。示例代碼以下所示:

const express = require('express');
var app = express();
app.use('/admin',(req,res)=>{
    res.send('成功匹配!')
})
app.listen(3000,'192.168.155.1');

此時當客戶端訪問http://192.168.155.1:3000/admin/new/path時,也能匹配上這個路由,從而執行內部的回調函數。

圖片描述

此時咱們能夠在回調函數內部使用req.originalUrlreq.baseUrlreq.path來獲得用戶輸入的網址當中的各個部分。示例代碼以下所示:

const express = require('express');
var app = express();
app.use('/admin',(req,res)=>{
    console.log(req.originalUrl);
    console.log(req.baseUrl);
    console.log(req.path);
    res.send('成功匹配!')
})
app.listen(3000,'192.168.155.1');

此時當客戶端訪問http://192.168.155.1:3000/admin/new/path時,結果爲:

圖片描述

當咱們使用app.use()這個路由中間件時,若是不寫網址或寫'/',則至關於與該指定ip與指定端口號下的全部網址進行匹配,由於全部網址均可以看作時'/'的擴展。app.use((req,res)=>{});。咱們能夠在路由表的最後寫上app.use((req,res)=>{res.status(404).send('沒有這個頁面!');});能夠作404頁面,當路由表當中全部路由都匹配不上時,則落入該路由項當中。咱們能夠用res.status(404).send('沒有這個頁面!');這種方式設置指定的狀態碼。

4、express提供靜態文件的伺服能力

相似於Apache之類的傳統服務器軟件,都默認提供靜態服務,有web容器和根目錄的概念。而對於Node.js來講,沒有web容器和根目錄的概念,因此當使用node.js來呈遞頁面時,須要進行頂層路由設計,來把用戶訪問的url地址和文件聯繫在一塊兒。但express提供靜態文件的伺服能力。咱們能夠用app.use(express.static(target));來指定用於提供靜態資源服務的文件夾,其中target表示爲提供靜態資源服務的文件夾的絕對物理地址。
在主文件1.js的同目錄下新建一個public文件夾。示例代碼以下所示:

const express = require('express');
const path = require('path');
var target = path.join(__dirname,'./public');
var app = express();
app.use(express.static(target));
app.listen(3000,'192.168.155.1');

此時咱們在public文件夾下新建一個index.html頁面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h2>提供靜態資源服務文件夾當中的首頁頁面!</h2>
</body>
</html>

此時public文件夾爲提供靜態資源服務的文件夾,當用戶端訪問http://192.168.155.1:3000時,默認進入public文件夾,顯示該文件夾當中的index.html頁面。

圖片描述

咱們也能夠在app.use()方法當中加上第一個參數,如app.use('/static',express.static(target));此時用戶須要輸入http://192.168.155.1:3000/static時,纔會至關於進入public文件夾,顯示該文件夾當中的index.html頁面。

咱們通常把提供靜態資源服務的路由代碼寫在上面,防止咱們在進行路由表設計時,與現有的路由發生衝突。

5、express與後臺模板引擎的配合能力

這裏主要介紹express與後臺模板引擎ejs的配合能力。咱們將ejs下載到項目文件夾的node_modules文件夾當中,在主文件1.js當中再也不須要使用require的方式進行引入。只要寫app.set("view engine","ejs");則完成了引包的工做。接下去再在當前目錄下新建一個固定文件名爲views的文件夾,把渲染的html頁面放在其中,後綴名改成.ejs。用res.render("文件名",{數據});
咱們在與主文件1.js的同目錄下新建一個views文件夾,裏面新建一個index.ejs的文件,內部代碼爲:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h2>後臺模板引擎:<%= a %></h2>
    <ul>
        <% for(var i = 0; i < list.length; i++){ %>
            <li><%= list[i] %></li>
        <% } %>
    </ul>
</body>
</html>

其中主文件1.js的示例代碼爲:

const express = require('express');
var app = express();
app.set("view engine","ejs");
app.get('/',(req,res)=>{
    res.render("index",{
        a:'ejs',
        list:['apple','banana','pear','tomato']
    })
})
app.listen(3000,'192.168.155.1');

此時結果爲:

圖片描述

若是咱們不想使用views文件夾,咱們能夠經過 app.set("views","abc");命令更改默認文件夾的名字。

6、express當中處理get、post的請求參數

get請求的參數在url當中,在express當中,再也不須要使用url模塊,直接使用req.query便可獲得客戶端經過get請求發送的參數對象。示例代碼以下所示:

const express = require('express');
var app = express();
app.get('/',(req,res)=>{
   console.log(req.query);
   res.send('成功!');
});
app.listen(3000,'192.168.155.1');

圖片描述

post請求在express當中不能直接得到,須要使用第三方模塊包body-parser。經過npm的方式完成模塊包的下載以後,經常使用的代碼爲const bodyParser = require('body-parser');app.use(bodyParser.urlencoded({extended:false}));,以後便可使用req.body來獲得參數對象。
咱們在views文件夾當中寫下一個form.ejs表單,示例代碼以下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <form action="http://192.168.155.1:3000" method="POST">
        <p>姓名:<input type="text" name="name"></p>
        <p>年齡:<input type="text" name="age"></p>
        <p><input type="submit" value="提交"></p>
    </form>
</body>
</html>

其中主文件1.js的示例代碼爲:

const express = require('express'); 
const bodyParser = require('body-parser');
var app = express();
app.set('view engine','ejs');
app.use(bodyParser.urlencoded({extended:false}));
app.get('/',(req,res)=>{
   res.render('form');
});
app.post('/',(req,res)=>{
    console.log(req.body);
    res.send('表單提交成功!');
});
app.listen(3000,'192.168.155.1');

此時在啓動在服務器以後,客戶端輸入網址http://192.168.155.1:3000時,呈遞該表單:

圖片描述

當完成表單填寫,並提交以後,結果爲:

圖片描述

這樣就實現了一個post方式表單提交的功能。

body-parser是一個輕量級的模塊包,僅僅適合處理表單內容的提交,但不能處理文件、圖片等多媒體文件的提交。若是客戶端提交的表單當中包含文件、圖片等,仍是建議使用formidable模塊包進行處理。

相關文章
相關標籤/搜索