express
基于Nodejs Web 的開發(fā)框架(老框架了 目前無人維護)
其他框架:Koa揽惹、egg
express快速入門
1.創(chuàng)建一個空的文件夾被饿,作為項目
2.初始化這個項目 npm init -y (生成版本庫)
3.安裝項目的依賴模塊 npm install --save express
4.git管理
4.1 git 初始化 git init
4.2 編輯 .gitignore(寫要忽略的文件夾名)文件
5.在項目目錄下創(chuàng)建一個 server.js 作為項目的入口文件(啟動文件)
6.在入口文件中寫代碼
7.設(shè)置npm腳本,并啟動搪搏。package.json -> scripts ->編輯key:value(要運行的代碼) -> 啟動:npm run key(key腳本名為start時run可忽略)
基于express快速搭建 后臺服務
1.引入express模塊
2.調(diào)用express方法狭握,生成express實例對象
3.設(shè)置路由,來響應不同的url地址請求
路由:一個url地址對應一個不同的路由處理程序(不同的url地址有不同的回調(diào)函數(shù)去響應)
4.監(jiān)聽端口號
const express = require('express'); //1
const server = express(); //2
server.get('/',(req,res) => { //3
res.send('express 搭建后臺服務');
});
server.listen(3000); //4
express 路由
語法:app.methods(path,callback)
- app 是 express 實例對象
- methods 是請求方法 get | post | put | update | delete |...
- path 就是路徑(url定值的 pathname )疯溺,必須以'/'開頭
- callback 回調(diào)函數(shù)论颅,路由的處理函數(shù)
- req
- res (這里的 req res 就是原生nodejs中的 req res。但比原生中要多一些屬性方法喝检,是express加上去的)
- next 是一個方法嗅辣,調(diào)用這個方法會讓路由繼續(xù)匹配下一個能匹配上的
重點:
1.路由代碼與 http 請求地址的對應關(guān)系
// GET http://localhost:3000/
server.get('/',(req,res) => {res.send('hello express') })
// GET http://localhost:3000/abc
server.get('/abc',(req,res) => {res.send('hello abc') })
- 如果有多個相同路徑的路由,那么會按照書寫順序執(zhí)行第一個
// GET http://localhost:3000/
server.get('/a',(req,res) => {res.send('hello') })
// GET http://localhost:3000/abc
server.get('/b',(req,res) => {res.send('world') })
//輸出hello
可以讓他按照順序找到寫一個匹配的路由 next()
// GET http://localhost:3000/
server.get('/abc',(req,res,next) => {
console.log('hello');
res.send('hello');
next(); //繼續(xù)往下尋找匹配的路由
})
// GET http://localhost:3000/abc
server.get('/abc',(req,res) => {
console.log('world'); //控制臺會輸出
res.send('world'); //報錯 上面已關(guān)閉請求
})
express 中 request(請求) 與 response(響應) (了解這兩個對象中被 express 增加的常用屬性和方法)
request(請求)
- req.query : 獲取get請求傳遞過來的參數(shù)(url的查詢參數(shù)串)
console.log(req.query); //{ name: 'vvv', age: '12' }
- req.body : 獲取post請求傳遞過來的參數(shù)
- 需要設(shè)置 express.json 和 express.urlencoded 這兩個中間件
//設(shè)置中間件
server.use(express.json());
server.use(express.urlencoded({extended:true}));
server.post('/',(req,res) => {
console.log(req.body); //{ name: '小薈', year: '3' }
res.send('xiaohui');
});
- req.cookies : 獲取瀏覽器傳遞過來的Cookies
- 需要使用 cookie-parser 中間件
- 1.安裝 cookie-parser npm install --save cookie-parser
- 2.在server.js中 引入cookie-parser模塊
- 3.在server.js中 使用cookie-parser
//獲取cookie req.cookies
const cookieParser = require('cookie-parser'); //引入模塊
server.use(cookieParser()); //設(shè)置中間件
server.get('/getcookie',(req,res) => {
console.log(req.cookies);
res.send('cookie獲取成功');
});
- req.get() 獲取指定的HTTP的請求頭
server.get('/',(req,res) => {
console.log(req.get('Host')); //localhost:3000
res.send('獲取指定的HTTP請求頭');
});
- req.params 獲取路由的動態(tài)參數(shù)parameters (輸出對象)
server.get('/:id',(req,res) => { // GET http://localhost:3000/a :id 動態(tài)路由參數(shù) 可匹配任意 可設(shè)置多個
console.log(req.params); //{ id: 'a' }
res.send('req.params 獲取路由的動態(tài)參數(shù)');
});
- req.hostname/req.ip : 獲取主機名和IP地址
server.get('/',(req,res) => {
console.log(req.hostname); //localhost
console.log(req.ip); //::1
res.send('req.hostname 獲取主機名和IP地址');
});
- req.path : 獲取請求路徑
server.get('/a',(req,res) => {
console.log(req.path); // /a
res.send('req.path 獲取請求路徑');
});
- req.protocol : 獲取協(xié)議類型
response(響應)
- res.cookie(name,value,[option]) : 設(shè)置Cookie
//設(shè)置cookie
server.get('/setcookie',(req,res) => {
res.cookie('name','女',{ //'name'不能為中文 {}cookie的選項對象 maxAge cookie保存的時間
maxAge : 1000*60*10
});
res.send('cookie設(shè)置成功');
});
res.clearCookie() : 清除cookie
res.set : 設(shè)置HTTP響應頭,傳入object可以一次設(shè)置多個頭
res.status : 設(shè)置HTTP狀態(tài)碼
server.get('/',(req,res) => {
res.set({'name':'xiaohui','age':18});
res.status(505).send('res.set 設(shè)置HTTP響應頭');
});
- res.send() : 傳送HTTP響應
- res.redirect : 重定向到明確的路徑挠说,需要有明確的HTTP status代碼澡谭,如果沒有,默認status代碼為 ‘302’ ‘Found’(頁面跳轉(zhuǎn))
- res.json : 傳送JSON響應 :可傳送對象 對象可轉(zhuǎn)成json的格式
- res.download() : 傳送指定路徑的文件
- res.sendFile(path,[option],[fn]) : 通過給定的路徑傳遞文件损俭,通過文件的擴展名設(shè)置響應頭Content-Type蛙奖。除非root選項已經(jīng)在參數(shù)options中設(shè)置了,path必須是絕對路徑
- res.render(view,[locals],[callback]) : 渲染視圖模板杆兵。渲染一個視圖雁仲,并把一個HTML字符串發(fā)送給客戶端,locals是一個對象琐脏,其屬性定義了視圖內(nèi)的局部變量攒砖。callback是一個回調(diào)函數(shù),如果提供了日裙,這個方法返回可能的錯誤信息和渲染字符串吹艇。如果有錯誤,這個方法會使用一個next(err)的內(nèi)部函數(shù)
express 靜態(tài)資源托管
通過 express 讓某個 url 輸出HTML頁面
1.讀文件
- fs.readFileSyne('文件路徑'); //讀出來的是buffer 會下載
- ①轉(zhuǎn)字符串 toString res.set('Content-Type','text/html; charset=utf-8'); //設(shè)置響應頭使瀏覽器輸出HTML
- ②直接使用 res.sendFile('需要渲染的頁面路徑[絕對路徑]'); path.resolve(__dirname,'');
server.get('/',(req,res) => {
let data = fs.readFileSync('./index/index.html');
console.log(data.toString());
res.set('Content-Type','text/html;charset=utf-8');
// res.sendFile(path.resolve(__dirname,'./index/index.html'));
});
使用 res.sendFile 每次引入不同文件都需要創(chuàng)建一個路由 太麻煩昂拂,需要靜態(tài)資源托管
靜態(tài)資源托管:將項目下的某個文件夾作為靜態(tài)資源托管的文件夾受神,后續(xù)只要想訪問這個文件夾的資源,都可通過某種規(guī)則的路徑來訪問
- 配置靜態(tài)資源托管的文件夾
//http://localhost:3000/
app.use(express.static(path.resolve(__dirname,'./public'))); //app為express實例 use使用中間件
//這時可將public文件看成web服務的根目錄 ./
//http://localhost:3000/css/style.css
- 也可通過設(shè)置來修改靜態(tài)資源托管的根路徑 app.use
//http://localhost:3000/static
app.use('/static',express.static(path.resolve(__dirname,'./public')));
express 中間件
- express.json()
- express.urlencode() (req.body)
- cookieParser()
- express.static()
中間件其實是一個攜帶req格侯、res鼻听、next這三個參數(shù)的函數(shù)财著,在請求與響應之間做一些中間處理的代碼
//定義一個中間件函數(shù)
const name = (req,res,next) => {
//需要做的事
next();
};
server.use(name); //調(diào)用這個中間件
-
注意
中間件函數(shù),在做完事情之后撑碴,必須調(diào)用 next() 否則程序不會往下走
中間件函數(shù)的調(diào)用必須放在需要使用的函數(shù)的前面
一撑教、 實現(xiàn)一個日志輸出的中間件
在這個項目中所有的請求,都要輸出一個日志灰羽。日志包含請求機器的IP地址驮履、請求路徑、請求時間
// 自己實現(xiàn)一個中間件廉嚼,中間件其實就是一個函數(shù)玫镐,攜帶者 req | res | next 這三個參數(shù)的函數(shù)
// 1. 定義這樣的一個中間件函數(shù)出來
const logger = (req, res, next) => {
console.log(
`請求的ip地址是:${req.ip}, 請求的路徑是:${
req.url
}, 請求的時間是:${new Date().getTime()}`
);
next();
};
// 2. 使用 server.use() 調(diào)用這個中間件 use 方法需要接受的是一個攜帶了 req| res| next 的函數(shù)
server.use(logger);
//在這個代碼后面的請求都能使用上這個中間件
中間件可以重寫 req、res 在其上面添加屬性方法
二怠噪、實現(xiàn)一個讓每個路由身上都能訪問到 req.requestTime 的中間件
const helloWorld = (req, res, next) => {
req.requestTime = new Date().getTime();
next();
};
server.use(helloWorld);
三恐似、思考實現(xiàn)一個cookieParser() 中間件 定義方法 給req加cookie(先得到cookie) cookie會隨http的請求攜帶在請求頭上 req.get 獲取指定的HTTP的請求頭->拆分成對象->寫入res的對象上
- req.get('Cookies') 請求頭中的數(shù)據(jù)
- req.cookies = 1中拿出的數(shù)據(jù)經(jīng)過轉(zhuǎn)化成的對象
四、可配置的中間件
希望這個中間件能夠通過不同的設(shè)置傍念,讓其 requestTime 是一個不同的格式
比如:1. 時間戳 2. 年份 3. 月份
const helloWorld = num => { //num 配置的參數(shù)
return (req, res, next) => { //閉包
let date = new Date();
if (num === 1) {
req.requestTime = date.getTime();
}
if (num === 2) {
req.requestTime = date.getFullYear();
}
if (num === 3) {
req.requestTime = date.getMonth();
}
next();
};
};
server.use(helloWorld(3));
- use 是全局中間件的設(shè)置
server.use(helloWorld(3));
- 可以局部設(shè)置中間件矫夷,給具體某一個路由設(shè)置某個中間(路由可有多個callback)
server.get("/a", helloWorld(1), (req, res) => {
console.log(req.requestTime);
res.send("a");
});
server.get("/b", helloWorld(2), (req, res) => {
console.log(req.requestTime);
res.send("b");
});
server.get("/c", helloWorld(3), (req, res) => {
console.log(req.requestTime);
res.send("c");
});
express 跨域
// 設(shè)置 cors 允許跨域
// 在響應頭中加入一個屬性 Access-Control-Allow-Origin
// 將這個屬性的值設(shè)置為 *
server.use((req, res, next) => {
res.set("Access-Control-Allow-Origin", "*");
// ...
next();
});
server.get("/getStudent", (req, res) => {
res.send({
code: 0,
msg: "獲取學生列表成功",
data: [{ id: 1, name: "張三", age: 18 }, { id: 2, name: "李四", age: 20 }]
});
});
- 此處應用 live-server 工具模塊 使HTML頁面在后臺打開
momentjs.cn - 日期時間格式化工具類
// server.use(helloWorld(2)); // YYYY-mm-dd yy-mm-dd hh:mm:ss
- npm install --save moment
- 引入并使用
const moment = require('moment');
const helloWorld = str => {
return (req, res, next) => {
req.requestTime = moment().format(str);
next();
};
};
server.get("/a", helloWorld("YYYY-MM-DD"), (req, res) => {
console.log(req.requestTime);
res.send("a");
});
服務端打開html頁面
live-server 一個 nodejs d 的工具模塊,能快速的幫我們將某個文件夾作為web服務的根目錄文件夾憋槐,并且以 localhost:8080 端口監(jiān)聽
1.全局安裝 npm install -g live-server
2.在某個文件夾下面双藕,使用 live-server 這個命令即可