做網(wǎng)站客戶怎么找常用的網(wǎng)絡(luò)推廣手段有哪些
目錄
- 初識 Express
- Express 簡介
- Express 的基本使用
- 托管靜態(tài)資源
- nodemon
- Express 路由
- 路由的概念
- 路由的使用
- Express 中間件
- 中間件的概念
- Express 中間件的初體驗(yàn)
- 中間件的分類
初識 Express
Express 簡介
什么是 Express?
- 官方給出的概念:Express 是基于 Node.js 平臺,快速、開放、極簡的 Web 開發(fā)框架。
- 通俗的理解:Express 的作用和 Node.js 內(nèi)置的 http 模塊類似,是專門用來
創(chuàng)建 Web 服務(wù)器
的。 - Express 的本質(zhì):就是一個 npm 上的第三方包,提供了快速創(chuàng)建 Web 服務(wù)器的便捷方法。
Express 的中文官網(wǎng): http://www.expressjs.com.cn/
進(jìn)一步理解 Express:
- 思考:不使用 Express 能否創(chuàng)建 Web 服務(wù)器?
答案:能,使用 Node.js 提供的原生 http 模塊即可。 - 思考:既生瑜何生亮(有了 http 內(nèi)置模塊,為什么還有用 Express)?
答案:http 內(nèi)置模塊用起來很復(fù)雜,開發(fā)效率低;Express 是基于內(nèi)置的 http 模塊進(jìn)一步封裝出來的,能夠極大的提高開發(fā)效率
。 - 思考:http 內(nèi)置模塊與 Express 是什么關(guān)系?
答案:類似于瀏覽器中 Web API 和 jQuery 的關(guān)系。后者是基于前者進(jìn)一步封裝出來的。
Express 能做什么?
對于前端程序員來說,最常見的兩種服務(wù)器,分別是:
Web 網(wǎng)站服務(wù)器
:專門對外提供 Web 網(wǎng)頁資源的服務(wù)器。API 接口服務(wù)器
:專門對外提供 API 接口的服務(wù)器。
使用 Express,我們可以方便、快速的創(chuàng)建 Web 網(wǎng)站的服務(wù)器或 API 接口的服務(wù)器。
Express 的基本使用
1. 安裝
在項(xiàng)目所處的目錄中,運(yùn)行如下的終端命令,即可將 express 安裝到項(xiàng)目中使用:
npm install express --save也可以安裝指定版本的express
npm install express@4.17.1
2. 創(chuàng)建基本的Web服務(wù)器
在安裝express的目錄下新建 app.js
文件,并插入如下代碼:
// 1.導(dǎo)入 express
const express = require('express')
// 2.創(chuàng)建 web 服務(wù)器
const app = express()
// 3.調(diào)用 app.listen(端口號, 啟動成功后的回調(diào)函數(shù)),啟動服務(wù)器
app.listen(80, () => {console.log('服務(wù)器已啟動(地址:http://127.0.0.1)')
})
然后在終端中運(yùn)行所創(chuàng)建的web服務(wù)器:
node app.js
如果運(yùn)行成功,就會在控制臺打印服務(wù)器已啟動(地址:http://127.0.0.1)
,在瀏覽器訪問鏈接可以看到返回的Cannot GET /
,因?yàn)槲覀冞€沒有寫具體的請求響應(yīng)內(nèi)容。
3.監(jiān)聽GET請求
通過 app.get()
方法,可以監(jiān)聽客戶端的 GET 請求,具體語法如下:
// 參數(shù)1:客戶端請求的 URL 地址
// 參數(shù)2:請求對應(yīng)的處理函數(shù)
// req:請求對象(包含了與請求相關(guān)的屬性和方法)
// res:響應(yīng)對象(包含了與響應(yīng)相關(guān)的屬性和方法)
app.get('請求URL', function(req, res) { /* 處理函數(shù) */ })
4.監(jiān)聽 POST 請求
通過 app.post()
方法,可以監(jiān)聽客戶端的 POST 請求,具體的語法格式如下:
// 參數(shù)1:客戶端請求的 URL 地址
// 參數(shù)2:請求對應(yīng)的處理函數(shù)
// req:請求對象(包含了與請求相關(guān)的屬性和方法)
// res:響應(yīng)對象(包含了與響應(yīng)相關(guān)的屬性和方法)
app.post('請求URL', function(req, res) { /* 處理函數(shù) */ })
5.把內(nèi)容響應(yīng)給客戶端
通過 res.send() 方法,可以把處理好的內(nèi)容,發(fā)送給客戶端:
const express = require('express')
const app = express()app.get('/user', function(req, res) {// 向客戶端發(fā)送 JSON 對象res.send({ name:'張三', age:20, gender:'男' })
})
app.post('/user', function(req, res) {// 向客戶端發(fā)送文本內(nèi)容res.send('post請求成功')
})app.listen(80, () => {console.log('服務(wù)器已啟動(地址:http://127.0.0.1)')
})
通過node 文件名
命令運(yùn)行服務(wù)器后,對http://127.0.0.1/user
發(fā)起get或post請求就可以分別得到res.send
發(fā)送的數(shù)據(jù)。
在瀏覽器打開http://127.0.0.1/user
也可以看到所定義的JSON對象在頁面上顯示,因?yàn)闉g覽器打開默認(rèn)是GET請求
6.獲取 URL 中攜帶的查詢參數(shù)
通過 req.query
對象,可以訪問到客戶端通過查詢字符串的形式,發(fā)送到服務(wù)器的參數(shù):
app.get('/', function(req, res) {// req.query 默認(rèn)是一個空對象// 客戶端可以使用 ?name=zs&age=20 這種查詢字符串形式,將參數(shù)發(fā)送到服務(wù)器// 發(fā)送到服務(wù)器的參數(shù)可以通過req.query訪問到// 如:req.query.nameconsole.log(req.query)
})
運(yùn)行服務(wù)器,瀏覽器訪問http://127.0.0.1/?name=zs&age=20
即可在服務(wù)器控制臺輸出如下內(nèi)容:
7. 獲取 URL 中的動態(tài)參數(shù)
通過 req.params
對象,可以訪問到 URL 中,通過 : 匹配到的動態(tài)參數(shù):
app.get('/user/:id', function(req, res) {// req.params 是一個空對象// 里面存放著通過 : 動態(tài)匹配到的參數(shù)值console.log(req.params)
})
運(yùn)行服務(wù)器,瀏覽器訪問http://127.0.0.1/user/2
即可在服務(wù)器控制臺輸出如下內(nèi)容:
托管靜態(tài)資源
1.express.static()
express 提供了一個非常好用的函數(shù),叫做 express.static()
,通過它,我們可以非常方便地創(chuàng)建
一個靜態(tài)資源服務(wù)器
,
例如,通過如下代碼就可以將 public 目錄下的圖片、CSS 文件、JavaScript 文件對外開放訪問了:
app.use(express.static('public'))
現(xiàn)在,你就可以訪問 public 目錄中的所有文件了:
http://localhost:3000/images/bg.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/login.js
注意:Express 在指定的靜態(tài)目錄中查找文件,并對外提供資源的訪問路徑。因此,
存放靜態(tài)文件的目錄名不會出現(xiàn)在 URL 中
。
2.托管多個靜態(tài)資源目錄
如果要托管多個靜態(tài)資源目錄,請多次調(diào)用 express.static()
函數(shù):
const express = require('express')
const app = express()app.use(express.static('public'))
app.use(express.static('files'))app.listen(80, () => {console.log('服務(wù)器已啟動(地址:http://127.0.0.1)')
})
3.掛載路徑前綴
如果希望在托管的靜態(tài)資源訪問路徑之前,掛載路徑前綴,則可以使用如下的方式:
app.use('/public', express.static('public'))
現(xiàn)在,你就可以通過帶有 /public 前綴地址來訪問 public 目錄中的文件了:
http://localhost:3000/public/images/kitten.jpg
http://localhost:3000/public/css/style.css
http://localhost:3000/public/js/app.js
nodemon
1.為什么要使用 nodemon
在編寫調(diào)試 Node.js 項(xiàng)目的時(shí)候,如果修改了項(xiàng)目的代碼,則需要頻繁的手動 close 掉,然后再重新啟動,非常繁瑣。
現(xiàn)在,我們可以使用 nodemon(https://www.npmjs.com/package/nodemon) 這個工具,它能夠監(jiān)聽項(xiàng)目文件的變動
,當(dāng)代碼被修改后,nodemon 會自動幫我們重啟項(xiàng)目
,極大方便了開發(fā)和調(diào)試。
2.安裝 nodemon
在終端中,運(yùn)行如下命令,即可將 nodemon 安裝為全局可用的工具:
npm install -g nodemon
3.使用 nodemon
當(dāng)基于 Node.js 編寫了一個網(wǎng)站應(yīng)用的時(shí)候,傳統(tǒng)的方式,是運(yùn)行 node app.js
命令,來啟動項(xiàng)目。
這樣做的壞處是:代碼被修改之后,需要手動重啟項(xiàng)目。
現(xiàn)在,我們可以將 node 命令替換為 nodemon 命令,使用 nodemon app.js
來啟動項(xiàng)目。
這樣做的好處是:代碼被修改之后,會被 nodemon 監(jiān)聽到,從而實(shí)現(xiàn)自動重啟項(xiàng)目
的效果。
node app.js
# 將上面的終端命令,替換為下面的終端命令,即可實(shí)現(xiàn)自動重啟項(xiàng)目的效果
nodemon app.js
Express 路由
路由的概念
1.什么是路由
廣義上來講,路由就是映射關(guān)系
。
2.Express 中的路由
在 Express 中,路由指的是客戶端的請求
與服務(wù)器處理函數(shù)
之間的映射關(guān)系
。
Express 中的路由分 3 部分組成,分別是請求的類型
、請求的 URL 地址
、處理函數(shù)
,格式如下:
app.METHOD(PATH, HANDLER)
3.路由的匹配過程
每當(dāng)一個請求到達(dá)服務(wù)器之后,需要先經(jīng)過路由的匹配
,只有匹配成功之后,才會調(diào)用對應(yīng)的處理函數(shù)。
在匹配時(shí),會按照路由的順序進(jìn)行匹配,如果請求類型
和請求的 URL
同時(shí)匹配成功,則 Express 會將這次請求,轉(zhuǎn)交給對應(yīng)的 function 函數(shù)進(jìn)行處理。
路由匹配的注意點(diǎn):
① 按照定義的先后順序
進(jìn)行匹配
② 請求類型
和請求的URL
同時(shí)匹配成功,才會調(diào)用對應(yīng)的處理函數(shù)
路由的使用
1.最簡單的用法
在 Express 中使用路由最簡單的方式,就是把路由掛載到 app 上,示例代碼如下:
const express = require('express')
// 創(chuàng)建Web服務(wù)器,并命名為 app
const app = express()// 掛載路由
// 匹配 GET 請求,且請求 URL 為 /
app.get('/', (req, res) => { res.send('hello world.') })
// 匹配 POST 請求,且請求 URL 為 /
app.post('/', (req, res) => { res.send('Post Request.') })app.listen(80, () => { console.log('http://127.0.0.1') })
2.模塊化路由
為了方便對路由進(jìn)行模塊化的管理
,Express 不建議將路由直接掛載到 app 上,而是推薦將路由抽離為單獨(dú)的模塊
。
將路由抽離為單獨(dú)模塊的步驟如下:
- 創(chuàng)建路由模塊對應(yīng)的
.js
文件 - 調(diào)用
express.Router()
函數(shù)創(chuàng)建路由對象 - 向路由對象上掛載具體的路由
- 使用
module.exports
向外共享路由對象 - 使用
app.use()
函數(shù)注冊路由模塊
3.創(chuàng)建路由模塊實(shí)例
在安裝Express的項(xiàng)目目錄下新建router.js
文件,并添加以下代碼:
// 這是路由模塊
// 1. 導(dǎo)入 express
const express = require('express')
// 2. 創(chuàng)建路由對象
const router = express.Router()// 3. 掛載具體的路由
router.get('/user/list', (req, res) => {res.send('Get user list.')
})
router.post('/user/add', (req, res) => {res.send('Add new user.')
})// 4. 向外導(dǎo)出路由對象
module.exports = router
新建app.js
文件,在app.js
中導(dǎo)入并使用路由模塊
const express = require('express')
const app = express()// 1. 導(dǎo)入路由模塊
const router = require('./router')
// 2. 注冊路由模塊,并添加統(tǒng)一的訪問前綴 /api ,便于分類
app.use('/api', router)// 注意: app.use() 函數(shù)的作用,就是來注冊全局中間件app.listen(80, () => {console.log('http://127.0.0.1')
})
當(dāng)請求地址為http://127.0.0.1/api/user/list
,且請求方式為 GET
時(shí),可以得到Get user list.
的響應(yīng)
Express 中間件
中間件的概念
1.什么是中間件
中間件(Middleware ),特指業(yè)務(wù)流程的中間處理環(huán)節(jié)
。
2.Express 中間件的調(diào)用流程
當(dāng)一個請求到達(dá) Express 的服務(wù)器之后,可以連續(xù)調(diào)用多個中間件,從而對這次請求進(jìn)行預(yù)處理。
3.Express 中間件的格式
Express 的中間件,本質(zhì)上就是一個function 處理函數(shù)
,Express 中間件的格式如下:
注意:中間件函數(shù)的形參列表中,必須包含 next 參數(shù)
。而路由處理函數(shù)中只包含 req 和 res。
4.next 函數(shù)的作用
next 函數(shù)
是實(shí)現(xiàn)多個中間件連續(xù)調(diào)用
的關(guān)鍵,它表示把流轉(zhuǎn)關(guān)系轉(zhuǎn)交
給下一個中間件或路由。
Express 中間件的初體驗(yàn)
1.定義中間件函數(shù)
可以通過如下的方式,定義一個最簡單的中間件函數(shù):
// 定義一個最簡單的中間件函數(shù)
const mw = function (req, res, next) {console.log('這是最簡單的中間件函數(shù)')// 把流轉(zhuǎn)關(guān)系,轉(zhuǎn)交給下一個中間件或路由next()
}// 將 mw 注冊為全局生效的中間件
app.use(mw)
或者也可以簡寫為如下格式:
app.use((req, res, next) => {console.log('這是最簡單的中間件函數(shù)')next()
})
實(shí)例:
const express = require('express')
const app = express()// 這是定義全局中間件的簡化形式
app.use((req, res, next) => {console.log('這是最簡單的中間件函數(shù)')next()
})app.get('/', (req, res) => {console.log('調(diào)用了 / 這個路由')res.send('Home page.')
})
app.get('/user', (req, res) => {console.log('調(diào)用了 /user 這個路由')res.send('User page.')
})app.listen(80, () => {console.log('http://127.0.0.1')})
2.中間件的作用
多個中間件之間,共享同一份 req 和 res
。基于這樣的特性,我們可以在上游
的中間件中,統(tǒng)一為 req 或 res 對象添加自定義的屬性或方法,供下游
的中間件或路由進(jìn)行使用。
3.定義多個全局中間件
可以使用 app.use()
連續(xù)定義多個全局中間件??蛻舳苏埱蟮竭_(dá)服務(wù)器之后,會按照中間件定義的先后順序
依次進(jìn)行調(diào)用,示例代碼如下:
const express = require('express')
const app = express()// 定義第一個全局中間件
app.use((req, res, next) => {console.log('調(diào)用了第1個全局中間件')next()
})
// 定義第二個全局中間件
app.use((req, res, next) => {console.log('調(diào)用了第2個全局中間件')next()
})// 定義一個路由
app.get('/user', (req, res) => {res.send('User page.')
})app.listen(80, () => {console.log('http://127.0.0.1')
})
4.局部生效的中間件
不使用 app.use() 定義的中間件,叫做局部生效的中間件
,示例代碼如下:
const express = require('express')
const app = express()// 1. 定義中間件函數(shù)
const mw1 = (req, res, next) => {console.log('調(diào)用了局部生效的中間件')next()
}// 2. 創(chuàng)建路由
app.get('/', mw1, (req, res) => {res.send('Home page.')
})
app.get('/user', (req, res) => {res.send('User page.')
})app.listen(80, function () {console.log('Express server running at http://127.0.0.1')
})
當(dāng)訪問http://127.0.0.1/
時(shí),終端輸出調(diào)用了局部生效的中間件
當(dāng)訪問http://127.0.0.1/user
時(shí),不調(diào)用定義的局部中間件函數(shù)
5.定義多個局部中間件
可以在路由中,通過如下兩種等價(jià)的方式,使用多個局部中間件:
const express = require('express')
const app = express()// 1. 定義中間件函數(shù)
const mw1 = (req, res, next) => {console.log('調(diào)用了第一個局部生效的中間件')next()
}const mw2 = (req, res, next) => {console.log('調(diào)用了第二個局部生效的中間件')next()
}// 2. 創(chuàng)建路由
app.get('/', [mw1, mw2], (req, res) => {res.send('Home page.')
})
app.get('/user', (req, res) => {res.send('User page.')
})app.listen(80, function () {console.log('Express server running at http://127.0.0.1')
})
6.了解中間件的5個使用注意事項(xiàng)
① 一定要在路由之前
注冊中間件
② 客戶端發(fā)送過來的請求,可以連續(xù)調(diào)用
多個中間件進(jìn)行處理
③ 執(zhí)行完中間件的業(yè)務(wù)代碼之后,不要忘記調(diào)用 next() 函數(shù)
④ 為了防止代碼邏輯混亂
,調(diào)用 next() 函數(shù)后不要再寫額外的代碼
⑤ 連續(xù)調(diào)用多個中間件時(shí),多個中間件之間,共享
req 和 res 對象
中間件的分類
為了方便大家理解和記憶中間件的使用,Express 官方把常見的中間件用法,分成了 5 大類,分別是:
- 應(yīng)用級別的中間件
- 路由級別的中間件
- 錯誤級別的中間件
- Express 內(nèi)置的中間件
- 第三方的中間件