国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

淺談Node.js輕量級Web框架Express4.x使用指南

2019-11-19 16:40:28
字體:
供稿:網(wǎng)友

Express是一個輕量級的Web框架,簡單、靈活

也是目前最流行的基于Nodejs的Web框架

通過它我們可以快速搭建功能完整的網(wǎng)站 (express 英文意思:特快列車)

Express現(xiàn)在是4.x版本,更新很快,并且不兼容舊版本,導(dǎo)致現(xiàn)在市面上很多優(yōu)秀的Node書籍過時

這篇文章是一篇入門級的Express使用,需要一定Node.js的基礎(chǔ)

Web應(yīng)用創(chuàng)建

首先要做的是下載express并引用

npm install express --save

全局安裝就+個-g

引用express

var express = require('express');var app = express();

通過app我們就可以使用各種express的API

在3.x版本的時候是這樣寫的

var app =express.createServer(); 

現(xiàn)在這個函數(shù)已經(jīng)被拋棄了

下面正式創(chuàng)建應(yīng)用

//app.jsvar express = require('express');var app = express();app.get('/', function(req, res){ res.send('Express');});app.listen(3000);

啟動之后就能給夠在頁面看到效果

$ node app.js

app.get()

上面的app.listen()就不多說了

用于監(jiān)聽端口

app.get(path, function(req, res){ }) 

用于用于處理客戶端向服務(wù)器發(fā)送的GET請求

path表示請求的路徑

回調(diào)函數(shù)的req和res是request和response的意思

request表示客戶端發(fā)送的HTTP請求信息

response表示服務(wù)器發(fā)送的HTTP響應(yīng)信息

使用res.send()可以向客戶端發(fā)送信息

//app.jsvar express = require('express');var app = express();app.get('/', function(req, res){ res.send('<h1>Express</h1>');});app.get('/demo', function(req, res){ res.send('<h1>Demo</h1>');})app.get('/*', function(req, res){ res.send('<h1>404<h1>');})app.listen(3000);
 

app.post()

app.post(path, function(req, res){ }) 

用于用于處理客戶端向服務(wù)器發(fā)送的POST請求

和GET請求不同,POST請求不會將信息放在url中

而是寫入請求頭中

它的解析有所不同,下面再說

app.all()

在此之前還要提一個概念――中間件

Middleware中間件在不同環(huán)境下有不同含義

而在我們express中,簡單說它就是一個特殊的函數(shù)

用來處理HTTP請求的函數(shù)

并且它有一個特點――處理完一個中間件可以傳遞給下一個中間件來處理

funciton(req, res, next){  ...  next();}

(如果不使用執(zhí)行next函數(shù),那么之后監(jiān)聽的函數(shù)也不會執(zhí)行)

可以向next中傳遞字符串參數(shù),代表拋出的錯誤信息

這樣當(dāng)數(shù)據(jù)往下傳遞的時候,中間件不再進(jìn)行處理

直到找到一個錯誤處理函數(shù)為止

app.all(path, function(req, res, next){ })的使用中

就需要我們定義這樣的中間件

這個方法可以過濾所有路徑上的請求

換句話說,在其他所有的中間件處理之前

必須先通過app.all()的中間件進(jìn)行處理

var express = require('express');var app = express();app.all('*', function(req, res, next){ res.writeHead(200, ':)'); next();});app.get('/', function(req, res){ res.end('<h1>Express</h1>');});app.get('/demo', function(req, res){ res.end('<h1>Demo</h1>');})app.get('/*', function(req, res){ res.end('<h1>404<h1>');})app.listen(3000);

這樣不論客戶端向我們發(fā)出了什么樣的路徑請求

服務(wù)器響應(yīng)信息前都會先打上響應(yīng)頭

app.use()

app.use([path, ]function(req, res, next){ }) 

這個方法一般情況是用來調(diào)用中間件的

與前面的函數(shù)不同,它的第一個path參數(shù)可以省略,默認(rèn)'/'

app.use(express.static(path.join(__dirname, '/public')));

上面的這個用法就是指定靜態(tài)文件的訪問路徑

通過next參數(shù)我們可以連續(xù)調(diào)用中間件函數(shù)

app.use(function(req, res, next){ console.log(1); next();});app.use(function(req, res, next){ console.log(2); next();});app.use(function(req, res, next){ console.log(3);});app.use(function(req, res, next){ console.log(4);});

當(dāng)發(fā)出網(wǎng)絡(luò)請求的時候

控制臺就會輸出 1 2 3

因為第三個中間件沒有調(diào)用next方法

所以處理到此為止

不會輸出4

app.use()除了調(diào)用中間件

還可以根據(jù)請求路徑的不同,返回不同信息

但我們一般不會這么用

//app.jsvar express = require('express');var app = express();app.use(function(req, res, next){ if(req.url == '/'){  res.end('<h1>Express</h1>'); }else{  next(); }});app.use(function(req, res, next){ if(req.url == '/demo'){  res.end('<h1>Demo</h1>'); }else{  next(); }});app.use(function(req, res, next){ res.end('<h1>404<h1>');});app.listen(3000);

請求與響應(yīng)

上面express中每一個回調(diào)函數(shù)都不可缺少req和res參數(shù)

重要性可見一斑

常見的req與res中的屬性/方法如下(原生node.js的req、res屬性/方法也可以使用)

Request對象:

API 含義
req.app 當(dāng)callback為外部文件時,用于訪問express的實例
req.baseUrl 獲取路由當(dāng)前安裝的URL路徑
req.body/cookies 獲得「請求主體」/ Cookies
req.fresh/stale 判斷請求是否還「新鮮」
req.hostname/ip 獲取主機名和IP地址
req.originalUrl 獲取原始請求URL
req.params 獲取路由的parameters
req.path 獲取請求路徑
req.protocol 獲取協(xié)議類型
req.query 獲取URL的查詢參數(shù)串
req.route 獲取當(dāng)前匹配的路由
req.subdomains 獲取子域名
req.acceptsCharsets 返回指定字符集的第一個可接受字符編碼
req.acceptsEncodings 返回指定字符集的第一個可接受字符編碼
req.acceptsLanguages 返回指定字符集的第一個可接受字符編碼
req.accepts() 檢查可接受的請求的文檔類型
req.get() 獲取指定的HTTP請求頭
req.is() 判斷請求頭Content-Type的MIME類型

Response對象:

API 含義
res.app 同req.app
res.append() 追加指定HTTP頭
res.set() 在res.append()后將重置之前設(shè)置的頭
res.cookie() 設(shè)置Cookie
res.clearCookie() 清除Cookie
res.download() 傳送指定路徑的文件
res.get() 返回指定的HTTP頭
res.json() 傳送JSON響應(yīng)
res.jsonp() 傳送JSONP響應(yīng)
res.location() 只設(shè)置響應(yīng)的Location HTTP頭,不設(shè)置狀態(tài)碼或者close response
res.redirect() 設(shè)置響應(yīng)的Location HTTP頭,并且設(shè)置狀態(tài)碼302
res.send() 傳送HTTP響應(yīng)
res.sendFile() 傳送指定路徑的文件 -會自動根據(jù)文件extension設(shè)定Content-Type
res.set() 設(shè)置HTTP頭,傳入object可以一次設(shè)置多個頭
res.status() 設(shè)置HTTP狀態(tài)碼
res.type() 設(shè)置Content-Type的MIME類型

挑一些重點

req.query

req.query可以獲取請求路徑參數(shù)的對象

向服務(wù)器發(fā)送請求 http://localhost:3000/?user=tester&pass[a]=123&pass[b]=456

//app.jsvar express = require('express');var app = express();app.get('/', function(req, res, next){ console.log(req.query); console.log(req.query.user); //tester console.log(req.query.pass.a); //123 console.log(req.query.pass.b); //456 res.end();});app.listen(3000);

req.params

req.params可以解析復(fù)雜路由規(guī)則上的屬性
(req.param綜合了req.query和req.param的功能,但是被移除了不要使用)

向服務(wù)器發(fā)送請求 http://localhost:3000/123456

//app.jsvar express = require('express');var app = express();app.get('/:id', function(req, res, next){ console.log(req.params.id); //123456 res.end();});app.listen(3000);

 這樣不論我在根路徑后輸入的是什么

都會被解析為req.params.id

res.send()

res.send用于向客戶端響應(yīng)信息 并且它的強大之處在于可以智能的處理我們傳遞的不同類型參數(shù)

app.get('/', function(req, res, next){ res.send('express');});

當(dāng)參數(shù)為字符串,會將響應(yīng)頭Content-Type默認(rèn)設(shè)置為text/html

也就是解析為html呈現(xiàn)在我們的頁面上

app.get('/', function(req, res){ res.send(200);});

當(dāng)參數(shù)為數(shù)字,會自動幫我們設(shè)置響應(yīng)體(狀態(tài)碼…)

app.get('/', function(req, res){ res.send([1, 2, 3]);});

當(dāng)參數(shù)為數(shù)組或?qū)ο螅鼤憫?yīng)一個JSON

res.redirect()

使用這個方法可以讓我們對網(wǎng)頁重定向

比如使用絕對url跳轉(zhuǎn)到不同的域名

app.get('/', function(req, res){ res.redirect('http://www.baidu.com');});

res.redirect()默認(rèn)響應(yīng)狀態(tài)碼是302

可以更改這個狀態(tài)碼作為res.redirect()的第一個參數(shù)

//app.jsvar express = require('express');var app = express();app.get('/', function(req, res){ res.redirect(302, 'demo');});app.get('/demo', function(req, res){ res.end();});app.listen(3000);

當(dāng)在url地址欄中輸入http://localhost:3000

頁面就會重定向到http://localhost:3000/demo

靜態(tài)資源

靜態(tài)資源就是指我們在開發(fā)中用到的css、js、img等等

它們需要存放到一個靜態(tài)資源目錄

當(dāng)瀏覽器發(fā)出了一個非HTML文件請求

服務(wù)器就會從這個靜態(tài)資源目錄下去查找文件

我們一般在根目錄下創(chuàng)建一個public文件來存儲

并在public中創(chuàng)建stylesheets、javascripts、images等文件夾

用來存儲特定類型的資源

指定靜態(tài)資源目錄的方法上面已經(jīng)提到了

var path = require('path');app.use(express.static(path.join(__dirname, 'public')));

比如說我們的html中有這樣的代碼

<link href="/javascripts/jquery.js" rel="external nofollow" rel="stylesheet" media="screen">

那么客戶端運行發(fā)出請求

服務(wù)器就會在public的javascripts文件夾下找到j(luò)Query.js靜態(tài)資源

模板引擎

express框架默認(rèn)是ejs和jade渲染模板

這里以jade為例

使用時肯定要下載

npm install jade --save

再通過app.set()指定查找模板文件的目錄(類似于靜態(tài)資源)

并指定模板文件后綴為jade

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

(如果不使用模板而使用原生html,app.set('view engine', 'html');)

如果我們想要訪問模板該怎么做呢?

很簡單,只需要一個方法res.render()

現(xiàn)在我寫了一個簡單的jade模板(關(guān)于jade語法超出本文討論范圍)

//views/index.jadedoctype htmlhtml head  title= title  link(rel='stylesheet', href='/stylesheets/style.css') body  h1= title  p= content

通過res.render渲染

//app.jsvar express = require('express');var path = require('path');var app = express();app.use(express.static(path.join(__dirname, 'public')));app.set('views', path.join(__dirname, 'views'));app.set('view engine', 'jade');app.get('/', function(req, res){ res.render('index', {  title: 'Express',  content: 'this is an example' });});app.listen(3000);

res.render()

res.render(view[, datas][, callback])

用于對網(wǎng)頁模板進(jìn)行渲染

第一個參數(shù)是要渲染的模板名稱

第二個參數(shù)是傳遞給模板的變量,以對象形式存儲,沒有可省略

第三個參數(shù)是渲染后回調(diào)函數(shù),可以省略

路由

路由的意思就是根據(jù)不同的路徑,來指定不同的處理方法

我們一般把不同的路由封裝進(jìn)不同的模塊

首先在根目錄下創(chuàng)建一個文件夾routes存儲路由

現(xiàn)在我在routes文件夾下創(chuàng)建倆個路由文件index.js和users.js

修改app.js

//app.jsvar express = require('express');var path = require('path');var app = express();var index = require('./routes/index');var users = require('./routes/users');app.use('/', index);app.use('/users', users);app.listen(3000);

這樣表示http://localhost:3000/的路由交給index處理

http://localhost:3000/users的路由交給users處理

下面簡單的實現(xiàn)一下路由

//routes/index.jsvar express = require('express');var router = express.Router();router.get('/', function(req, res){ res.end('index');});router.get('/123', function(){ res.end(123);});module.exports = router;
//routes/users.jsvar express = require('express');var router = express.Router();router.get('/', function(req, res) { res.end('users');});module.exports = router;

通過express.Router()創(chuàng)建的router就像一個mini版的app一樣

app能做的,router都能做

只是我們把邏輯都封裝到了各個路由模塊中

上面代碼的結(jié)果:

body-parser中間件

作為一個入門級文章

最后就來淺顯的談一個中間件body-parser吧

其實express在3.x版本中內(nèi)置了很多中間件

但是4.x版本就將出static以外的所有中間件全部抽離出來了

所以就需要我們單獨安裝

對照表如下:

Express 3.0 Express 4.0
bodyParser body-parser
compress compression
cookieSession cookie-session
logger morgan
cookieParser cookie-parser
session express-session
favicon static-favicon
response-time response-time
error-handler errorhandler
method-override method-override
timeout connect-timeout
vhost vhost
csrf csurf

剛才就提到了POST請求有所不同

不同的地方就在于我們需要body-parser這個中間件來處理數(shù)據(jù)

通過req.body來獲得數(shù)據(jù)

首先使用前不要忘記下載

npm install body-parser --save
//app.jsvar express = require('express');var bodyParser = require('body-parser');var path = require('path');var app = express();app.use(bodyParser.json());app.use(bodyParser.urlencoded({ extended: false }));app.get('/', function(req, res){ res.send('<form method="POST" action="./form">/       <input type="text" name="user">/       <input type="submit">/      </form>');});app.post('/form', function(req, res){ console.log(req.body); var user = req.body.user; res.send('賬號: ' + user);});app.listen(3000);

下面這四個方法分別用于對body內(nèi)容采取不同的處理方法

  1. bodyParser.json(options) 處理JSON數(shù)據(jù)
  2. bodyParser.raw(options) 處理buffer數(shù)據(jù)
  3. bodyParser.text(options) 處理文本數(shù)據(jù)
  4. bodyParser.urlencoded(options) 處理UTF-8編碼數(shù)據(jù)

這樣我首先通過get請求獲取主頁面

提交表單向服務(wù)器發(fā)送post請求

服務(wù)器響應(yīng)結(jié)果

express-generator

通過express-generator應(yīng)用生成器

可以為我們快速生成項目雛形

在你要生成項目的目錄中下載express-generator

npm install express-generator

然后輸入

express <項目文件名>

這樣express就會把必要的文件夾以及代碼快速生成了

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 中卫市| 曲阜市| 镇原县| 涞水县| 安龙县| 太湖县| 德化县| 拜泉县| 邮箱| 和平县| 朝阳县| 巴马| 浦江县| 聂拉木县| 阿拉善盟| 文昌市| 甘肃省| 巨鹿县| 赣榆县| 宣恩县| 南川市| 永福县| 永定县| 博罗县| 齐河县| 泰来县| 桃园县| 安西县| 张家界市| 镇安县| 修水县| 陈巴尔虎旗| 德化县| 彭泽县| 梁山县| 汪清县| 若羌县| 旬阳县| 隆昌县| 淳化县| 山阳县|