介紹
核心功能:
- 允許設立中間件響應 http 請求;
- 定義用於執行 HTTP 方法和 URL 不同動作的路由表;
- 允許動態渲染基於參數傳遞給模板 HTML 頁面
安裝
-
cmd 下載
$ npm install express --save
上述命令在本地 node_modules 目錄目錄保存安裝,並創建一個目錄 express 在 node_modules 裏,應該使用 express 安裝以下幾個重要的模塊
-
body-parser: 處理 JSON,Raw,Text,URL 編碼的表單數據的中間件
-
cookie-parser: 解析 cookie 頭 ,填充 req.cookies 通過cookie 名字鍵控對象
-
multer: 處理 multipart/formData 的中間件
$ npm install body-parser --save $ npm install cookie-parser --save $ npm install multer --save
-
-
package.json 間接安裝
mkdir express//創建 express 文件夾
express 目錄下創建 package.json 文件
{ "name": "express", "description": "express test app", "version": "0.0.1", "private": "true", "dependencies": { "express": "3.x" } }
cmd 執行下述命令
npm install
mkdir 一個 server.js
const express = require("express"); var server = express();
在此實例中,你可以通過
server.VERB()
定義路由,req
和res
對象是node 原生提供的,可執行res.pipe()
,req.on('data',callback)
等任何命令在未安裝 Express 的情況下Express 給這些對象加了一個封裝好的方法,比如
res.send()
,它會設置 Content-Lengthserver.get('/hello.txt',function(req,res){ res.send('Hello World'); });
執行
server.listen()
綁定並監聽連接server.listen(8080,function(){ console.log('Listening on port %d',server.address().port); });
Hello world 實例
下述爲一個基本的Express 應用程序,可啓動服務器,偵聽端口8080等待連接,
const express = require("express");
var app = express();
app.get('/',function(req,res){
res.send('Hello World!');
})
var server = app.listen(8080,function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
})
保存上述代碼至文件名爲 server.js 的文件中,並在 cmd 中$ node server.js
看到輸出
Example app listening at http://0.0.0.0:8080
在任何瀏覽器打開 http://127.0.0.1:8080/
Request & Response
Express 應用程序利用一個回調函數,它的參數是 request 和 response 對象
app.get('/',function(req,res){
// --
})
- Request 對象 – 請求對象表示HTTP請求和具有用於請求查詢的字符串,參數,主體,HTTP報頭等屬性
- Response 對象 – 響應對象表示HTTP響應Express應用程序發送時,他得到一個HTTP請求
基本的路由
路由,確定應用程序如何響應客戶機請求到特定端點,這是一個URI(路徑)和特定的HTTP請求方法(GET,POST等)
擴展上述 Hello World 程序添加功能
const express = require("express");
var app = express();
//This responds with "Hello World" on the homepage
app.get('/',function(req,res){
console.log('Got a GET request for the homepage');
res.send('Hello GET');
})
//This responds a POST request for the homepage
app.post('/',function(req,res){
console.log('Got a POST request for the homepage');
res.send('Hello POST');
})
//This responds a Delete request for the /del_user page
app.delete('/',function(req,res){
console.log('Got a DELETE request for /del_user');
res.send('Hello DELETE');
})
//This responds a GET request for the /list_user page
app.get('/',function(req,res){
console.log('Got a GET request for /list_user');
res.send('Hello Listing');
})
//This responds a GET request for abcd,abxcd,ab123cdcon,and so on
app.get('/',function(req,res){
console.log('Got a GET request for /ab*cd');
res.send('Page Pattern Match');
})
var server = app.listen(8080,function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
})
提供靜態文件服務
express 提供內置中間件 express.static 用於處理靜態文件,如圖像,CSS,JS等
只需在那裏把靜態資源,到 express.static 中間件開始直接服務於文件傳遞目錄得名稱
【假設】把圖片,css,JS文件放在指定目錄 public
app.use(express.static('public'));
將上述代碼添加至 “Hello World ”應用程序以添加處理靜態文件功能
GET方法
栗子
通過使用HTML表單使用GET方法傳遞兩個值。我們將使用server.js路由器裏面 process_get 來處理該輸入
//index.html
<html>
<body>
<form action="http://127.0.0.1:8081/process_get" method="GET">
First Name: <input type="text" name="first_name"> <br>
Last Name: <input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html>
const express = require("express");
var app = express();
app.use(express.static('publuc'));
app.get('/',function(req,res){
res.readFile(__dirname + '/' + 'index.html');
});
app.get('/process_get',function(req,res){
response = {
first_name:req.query.first_name,
last_name:req.query.last_name
};
console.log(response);
res.end(JSON.stringify(response));
});
var server = app.listen(8081,function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
});
File 上傳
創建一個文件上傳表單。這種形式的方法屬性設置爲POST,以及enctype屬性設置爲 multipart/form-data
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="http://127.0.0.1:8081/file_upload" method="POST"
enctype="multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
</html>
const express = require('express');
const app = express();
const fs = require('fs');
var bodyParser = require('body-parser');
var multer = require('multer');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended:false}));
app.use(multer({dest:'/txt/'}));
app.get('/index.html',function(req,res){
res.readFile(__dirname + '/' + 'index.html');
})
app.post('/file_upload',function(req,res){
console.log(req.files.file.name);
console.log(req.files.file.path);
console.log(req.files.file.type);
var file = __dirname + "/" + req.files.file.name;
fs.readFile(req.files.file.path,function(err,data){
fs.writeFile(file,data,function(err){
if(err){
console.log(err);
}else{
response = {
message:'File uploaded successfully',
filename:req.files.file.name
};
}
console.log(response);
res.end(JSON.stringify(response));
});
});
})
var server = app.listen(8081,function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port)
})
cookie,session
-
cookie:
瀏覽器保存數據,每次請求均會被帶來,保存於客戶端,不安全,內存有限,可獨立存在
-
發送cookie
res.cookie(name,value,{path:'/',maxAge://最長保存時間ms })
-
讀取–中間件(cookie-parser)
const cookieParser = require('cookie-parser'); server.use(cookieParser('密鑰'));
-
刪除
server.use('/',function(req,res){ res.clearCookie('user'); });
-
加密
-
req.sercet = '密鑰'
res.cookie(name,value,{signed:true});
‘【栗子】
req.secret = 'abcd'; res.cookie('user','meng',{signed:true}); console.log(req.signedCookies); //簽名的cookie console.log(req.cookies); //未簽名的cookie
-
-
-
session–(cookie-session)
數據保存於服務端,安全,內存無限,基於cookie 實現的,不可獨立存在
若想使用
server.use(cookieSession())
,必需有server.use(cookieParser)
cookie 中有一個 sessionID,服務器利用 sessionID 找到 session 文件,讀取,寫入
-
隱患:session 劫持,cookie-session 強制有密鑰
-
獲取
server.use(cookieSession(){ name: , keys:[], maxAge: })
-
處理
server.use('/',function(req,res){ req.session['count'] = ; });
-
刪除
delete req.session;
-
Cookies 管理
可使用發送 cookie 來Node.js 加載服務器,他可處理使用下面的中間件選項、
【栗子】
打印所有客戶端發送的cookie
const express = require('express');
const cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get('/',function(req,res){
console.log('Cookies: ',req.cookies)
})
app.listen(8081);
body-parser
http 請求中,put,post,patch 三種請求方法中包含請求體,即request,在 Node.js 原生的 http 模塊中,請求體是要基於流的方式來接受和解析的
body-parser 是一個 http 請求體解析的中間件,使用此模塊可解析 JSON,Raw,Text,URL-encoded 格式的請求體
Node 原生的 http 模塊中,是將用戶請求數據封裝於用於請求的對象 req 中,此對象是一個 IncomingMessage,也爲一個可讀流文件。原生Http 服務器,或不依賴第三方解析模塊時,可用下面的方法請求並且解析請求體
const http = require("http");
http.createServer(function(req,res){
if(req.method.toLowerCase() == 'post'){
var body = '';
//接收數據
req.on('data',function(chunk){
body += chunk;
});
//開始解析
req.on('end',function(){
if(req.headers['content-type'].indexOf('application/json') !== -1){
JSON.parse(body);
}else if(req.headers['content-type'].indexOf('application/octet-stream')!==-1){
//Raw 格式請求體解析
}else if(req.headers['content-type'].indexOf('text/plain')!==-1){
//text 格式請求體解析
}else if(req.headers['content-type'].indexOf('application/x-www-form-urlencoded')){
//url-encoded 格式請求體解析
}else{
//其他格式解析
}
});
}else{
res.end('其他方式提交');
}
}).listen(8080);
在實際項目中,不同路徑可能要求用戶使用不同的內容類型,body-parser還支持爲單個express路由添加請求體解析
var express = require('express');
var bodyParser = require('body-parser');
var app = new express();
//創建application/json解析
var jsonParser = bodyParser.json();
//創建application/x-www-form-urlencoded
var urlencodedParser = bodyParser.urlencoded({extended: false});
//POST /login 中獲取URL編碼的請求體
app.post('/login', urlencodedParser, function(req, res){
if(!req.body) return res.sendStatus(400);
res.send('welcome, ' + req.body.username);
})
//POST /api/users 獲取JSON編碼的請求體
app.post('/api/users', jsonParser, function(req,res){
if(!req.body) return res.sendStatus(400);
//create user in req.body
})
指定請求類型
指定時可以通過在解析方法中添加type參數修改指定Content-Type的解析方式。
比如,對text/plain內容類型使用JSON解析
app.use(bodyParser.json({type: 'text/plain'}))
body-parser模塊的API
當請求體解析之後,解析值會被放到req.body屬性中,當內容爲空時候,爲一個空對象{}
bodyParser.json()--解析JSON格式
bodyParser.raw()--解析二進制格式
bodyParser.text()--解析文本格式
bodyParser.urlencoded()--解析文本格式