NodeJS express

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') })
  1. 如果有多個相同路徑的路由,那么會按照書寫順序執(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 中間件

  1. express.json()
  2. express.urlencode() (req.body)
  3. cookieParser()
  4. 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的對象上

  1. req.get('Cookies') 請求頭中的數(shù)據(jù)
  2. 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

  1. npm install --save moment
  2. 引入并使用
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 這個命令即可

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阳仔,隨后出現(xiàn)的幾起案子忧陪,更是在濱河造成了極大的恐慌,老刑警劉巖近范,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘶摊,死亡現(xiàn)場離奇詭異,居然都是意外死亡评矩,警方通過查閱死者的電腦和手機叶堆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斥杜,“玉大人虱颗,你說我怎么就攤上這事≌嵛梗” “怎么了上枕?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弱恒。 經(jīng)常有香客問我,道長棋恼,這世上最難降的妖魔是什么返弹? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任锈玉,我火速辦了婚禮,結(jié)果婚禮上义起,老公的妹妹穿的比我還像新娘拉背。我一直安慰自己,他們只是感情好默终,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布椅棺。 她就那樣靜靜地躺著,像睡著了一般齐蔽。 火紅的嫁衣襯著肌膚如雪两疚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天含滴,我揣著相機與錄音诱渤,去河邊找鬼。 笑死谈况,一個胖子當著我的面吹牛勺美,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碑韵,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼赡茸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了祝闻?” 一聲冷哼從身側(cè)響起占卧,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎治筒,沒想到半個月后屉栓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡耸袜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年友多,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片堤框。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡域滥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜈抓,到底是詐尸還是另有隱情启绰,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布沟使,位于F島的核電站委可,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜着倾,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一拾酝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卡者,春花似錦蒿囤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恒傻,卻和暖如春脸侥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背碌冶。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工湿痢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扑庞。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓譬重,卻偏偏與公主長得像,于是被迫代替她去往敵國和親罐氨。 傳聞我的和親對象是個殘疾皇子臀规,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容