溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

express怎么使用

發(fā)布時(shí)間:2022-01-26 09:34:40 來(lái)源:億速云 閱讀:210 作者:iii 欄目:web開(kāi)發(fā)

這篇文章主要介紹“express怎么使用”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“express怎么使用”文章能幫助大家解決問(wèn)題。

express怎么使用

express

簡(jiǎn)介

Express 是基于 Node.js 平臺(tái),快速、開(kāi)放、極簡(jiǎn)的 Web 開(kāi)發(fā)框架。搭建web服務(wù)器

Express 的本質(zhì):就是一個(gè) npm 上的第三方包,提供了快速創(chuàng)建 Web 服務(wù)器的便捷方法。

使用Express開(kāi)發(fā)框架可以非常方便、快速的創(chuàng)建Web網(wǎng)站的服務(wù)器或API接口的服務(wù)器

官方網(wǎng)址:https://www.expressjs.com.cn/

簡(jiǎn)單使用

下載安裝:

npm init -ynpm i express -S

使用步驟:

  1. 導(dǎo)入包

  2. 創(chuàng)建服務(wù)器

  3. 處理請(qǐng)求

  4. 監(jiān)聽(tīng)端口

const express = require('express')const app = express()app.get(路由,回調(diào)) // get是請(qǐng)求方法app.listen(端口號(hào))

路由方法

請(qǐng)求方法還支持:

get - 查詢請(qǐng)求 - 條件在地址欄

post - 新增請(qǐng)求 - 數(shù)據(jù)在請(qǐng)求主體

put - 修改請(qǐng)求 - 條件在地址欄 - 數(shù)據(jù)在請(qǐng)求主體

delete - 刪除請(qǐng)求 - 條件在地址欄

各個(gè)動(dòng)詞方法用來(lái)處理對(duì)應(yīng)的請(qǐng)求。不過(guò)有一個(gè)方法除外:

app.all() // 可以用來(lái)處理任意請(qǐng)求方式

雖然all方法可以處理任意請(qǐng)求,但是盡量少用,甚至盡量不要使用。

使用postman進(jìn)行調(diào)試

路由路徑

完全匹配

// 匹配根路徑的請(qǐng)求app.get('/', function (req, res) {
  res.send('root');});// 匹配 /about 路徑的請(qǐng)求app.get('/about', function (req, res) {
  res.send('about');});// 匹配 /random.text 路徑的請(qǐng)求app.get('/random.text', function (req, res) {
  res.send('random.text');});

不完全匹配

// 匹配 acd 和 abcdapp.get('/ab?cd', function(req, res) {
  res.send('ab?cd');});// 匹配 abcd、abbcd、abbbcd等app.get('/ab+cd', function(req, res) {
  res.send('ab+cd');});// 匹配 abcd、abxcd、abRABDOMcd、ab123cd等app.get('/ab*cd', function(req, res) {
  res.send('ab*cd');});// 匹配 /abe 和 /abcdeapp.get('/ab(cd)?e', function(req, res) {
 res.send('ab(cd)?e');});

字符 ?、+、* 和 () 是正則表達(dá)式的子集,- 和 . 在基于字符串的路徑中按照字面值解釋。

正則匹配:

// 匹配任何路徑中含有 a 的路徑:app.get(/a/, function(req, res) {
  res.send('/a/');});// 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man等app.get(/.*fly$/, function(req, res) {
  res.send('/.*fly$/');});

路由多次處理

使用一個(gè)回調(diào)函數(shù)處理路由:

app.get('/example/a', function (req, res) {
  res.send('Hello from A!');});

多次處理:

app.get('/example/b', function (req, res, next) {
  console.log('這處理完之后會(huì)交給下一個(gè)函數(shù)處理');
  next();}, function (req, res) {
  res.send('Hello from B!');});

使用回調(diào)函數(shù)數(shù)組處理路由:

var cb0 = function (req, res, next) {
  console.log('CB0')
  next()}var cb1 = function (req, res, next) {
  console.log('CB1')
  next()}var cb2 = function (req, res) {
  res.send('Hello from C!')}app.get('/example/c', [cb0, cb1, cb2])

混合使用函數(shù)和函數(shù)數(shù)組處理路由:

var cb0 = function (req, res, next) {
  console.log('CB0')
  next()}var cb1 = function (req, res, next) {
  console.log('CB1')
  next()}app.get('/example/d', [cb0, cb1], function (req, res, next) {
  console.log('response will be sent by the next function ...')
  next()}, function (req, res) 
        {
  res.send('Hello from D!')})

響應(yīng)方法

res.download() // 提示下載文件。	
res.end() // 終結(jié)響應(yīng)處理流程。
res.json() // 發(fā)送一個(gè) JSON 格式的響應(yīng)。
res.jsonp() // 發(fā)送一個(gè)支持 JSONP 的 JSON 格式的響應(yīng)。
res.redirect() // 重定向請(qǐng)求。
res.render() // 渲染視圖模板。
res.send() // 發(fā)送各種類型的響應(yīng)。
res.sendFile() // 以八位字節(jié)流的形式發(fā)送文件。
res.sendStatus() // 設(shè)置響應(yīng)狀態(tài)代碼,并將其以字符串形式作為響應(yīng)體的一部分發(fā)送。

download示例:

// 響應(yīng)下載 - res.download(被下載的源文件,下載后的文件名稱,回調(diào)函數(shù))res.download("./test.html",'b.html',err=>{
    if(err){
        console.log("下載失敗");
    }else{
        console.log("下載成功");
    }})

json示例:

// 給客戶端響應(yīng)json數(shù)據(jù)// res.json(json格式的數(shù)據(jù))let obj = {
    name:"張三",
    age:12,
    wife:"翠花",
    children:['阿大','阿二','小明']}res.json(obj)

jsonp示例:

// 給客戶端發(fā)起的jsonp請(qǐng)求做響應(yīng),響應(yīng)的是json數(shù)據(jù)// res.jsonp(json格式的數(shù)據(jù))let obj = {
    name:"張三",
    age:12,
    wife:"翠花",
    children:['阿大','阿二','小明']}res.jsonp(obj)

redirect示例:

// res.redirect() 用來(lái)跳轉(zhuǎn)路由的 - /a這個(gè)路由,其實(shí)/b這個(gè)路由就正好可以處理他,就可以在/a這個(gè)路由處理中,將這次請(qǐng)求交給/b這個(gè)路由去處理res.redirect('/index')app.get('/index',(req,res)=>{
    let data = fs.readFileSync('./test.html')
    res.end(data)})

send示例:

// res.send() - 用于給客戶端響應(yīng)字符串的 - 字符串中如果是標(biāo)簽,可解析成html - 自動(dòng)設(shè)置數(shù)據(jù)類型和編碼let html = `
<h3>這是一個(gè)h3標(biāo)簽</h3>
`// res.end 不會(huì)自動(dòng)設(shè)置數(shù)據(jù)類型,也不會(huì)設(shè)置編碼// res.end(html)res.send(html)

sendFile示例:

// res.sendFile() 用于給客戶端響應(yīng)一個(gè)文件res.sendFile(__dirname + '/test.html')

sendStatus示例:

// sendStatus是自動(dòng)設(shè)置響應(yīng)狀態(tài)碼,并將對(duì)應(yīng)的響應(yīng)狀態(tài)描述響應(yīng)給客戶端
res.sendStatus(404) // 響應(yīng) not found
res.sendStatus(200) // 響應(yīng) ok

請(qǐng)求對(duì)象的屬性

req.url // 請(qǐng)求的路徑 - 如果有?傳參,這個(gè)路徑中也會(huì)帶有參數(shù)
req.method // 請(qǐng)求方法
req.path // 請(qǐng)求路徑 - 如果有?傳參,這個(gè)路徑中不包含參數(shù)
req.protocol // 協(xié)議
req.params // 獲取get請(qǐng)求的參數(shù) - 針對(duì)動(dòng)態(tài)路由傳參 - restful風(fēng)格的參數(shù) - 最終獲取到的是對(duì)象,對(duì)象的鍵,就是路徑指定的名稱
req.query // 獲取get請(qǐng)求的參數(shù) - 針對(duì)傳統(tǒng)形式傳參 - 使用?參數(shù) - 最終獲取到的是對(duì)象

靜態(tài)資源托管

express提供了一個(gè)非常好用的方法,叫做 express.static(),通過(guò)此方法,可以非常方便地創(chuàng)建一個(gè)靜態(tài)web資源服務(wù)器:

app.use(express.static('public'))
// app.use()表示使用(中間件)
// 現(xiàn)在可以訪問(wèn)public目錄下所有的文件 
// 如public/aa.jpg文件,則可以通過(guò) : http://xxxx/images/aa.jpg

express還支持給靜態(tài)資源文件創(chuàng)建一個(gè)虛擬的文件前綴(實(shí)際上文件系統(tǒng)中并不存在),可以使用 express.static 函數(shù)指定一個(gè)虛擬的靜態(tài)目錄,就像下面這樣:

前綴的使用意義:

  • 可以迷惑別人,一定程度上阻止別人猜測(cè)我們服務(wù)器的目錄結(jié)構(gòu)

  • 可以幫助我們更好的組織和管理靜態(tài)資源

app.use('/static', express.static('public'))

前綴前面的“/”必須要加,否則就錯(cuò)?!?04】

現(xiàn)在你可以使用 /static 作為前綴來(lái)加載 public 文件夾下的文件了:

http://localhost:3000/static/images/kitten.jpg
http://localhost:3000/static/css/style.css
http://localhost:3000/static/js/app.js
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/hello.html

使用app.use()方法一般寫(xiě)在具體的路由監(jiān)聽(tīng)之前。

每個(gè)應(yīng)用可有多個(gè)靜態(tài)目錄。

app.use(express.static('public'))app.use(express.static('uploads'))app.use(express.static('files'))

路由

介紹

路由在生活中如撥打服務(wù)電話時(shí),按數(shù)字幾能處理什么樣的處理,它就是類似于按鍵與服務(wù)之間的映射關(guān)系。在Express中,路由指的就是客戶端發(fā)起的請(qǐng)求(地址)與服務(wù)器端處理方法(函數(shù))之間的映射關(guān)系。

express中的路由分3部份組成,分別是請(qǐng)求類型(方法)、請(qǐng)求uri(地址)和對(duì)應(yīng)的處理函數(shù)

當(dāng)一個(gè)客戶端請(qǐng)求到達(dá)服務(wù)端之后,先經(jīng)過(guò)路由規(guī)則匹配,只有匹配成功之后,才會(huì)調(diào)用對(duì)應(yīng)的處理函數(shù)。在匹配時(shí),會(huì)按照路由的順序進(jìn)行匹配,如果請(qǐng)求類型和請(qǐng)求的 URL 同時(shí)匹配成功,則 Express 會(huì)將這次請(qǐng)求,轉(zhuǎn)交給對(duì)應(yīng)的函數(shù)進(jìn)行處理。

app.<get/post/put/delete/use>(uri,(req,res)=>{})// use方法并不是請(qǐng)求類型方法,但是它放的位置與請(qǐng)求方法一致

路由模塊化

含義:將原本可能寫(xiě)在一個(gè)文件中的路由規(guī)則,拆分成若干個(gè)路由文件(js文件,一個(gè)js文件就是一個(gè)模塊)。

顧名思義,將路由進(jìn)行模塊化,以模塊(js文件)為單位進(jìn)行管理,物以類聚。

核心思想:能拆就拆(拆到不能拆為止,解耦,高內(nèi)聚,低耦合)。

在開(kāi)發(fā)項(xiàng)目時(shí),如果將所有的路由規(guī)則都掛載到入口文件中,程序編寫(xiě)和維護(hù)都變得更加困難。所以express為了路由的模塊化管理功能,通過(guò)express.Router()方法創(chuàng)建路由模塊化處理程序,可以將不同業(yè)務(wù)需求分開(kāi)到不同的模塊中,從而便于代碼的維護(hù)和項(xiàng)目擴(kuò)展。

步驟:

  1. 指定那個(gè)路徑開(kāi)頭的請(qǐng)求,用app.use(路徑開(kāi)頭,處理模塊)

    app.use('/admin',adminRouter) // /admin開(kāi)頭的請(qǐng)求路徑,交給adminRouter模塊處理app.use('/front',frontRouter) // /front開(kāi)頭的請(qǐng)求路徑,交給frontRouter模塊處理
  2. 這個(gè)模塊未定義,定義這個(gè)模塊

    let {adminRouter} = require('./admin/admin')let {frontRouter} = require('./front/front')
  3. 導(dǎo)入的文件還未定義,創(chuàng)建文件

    const express = require('express')const adminRouter = express.Router() // 創(chuàng)建路由對(duì)象// 通過(guò)路由對(duì)象處理剩余的請(qǐng)求adminRouter.get('/goods',(req,res)=>{
        res.send('這是admin模塊的goods頁(yè)面')})// 導(dǎo)出模塊module.exports = {adminRouter}

此時(shí),我們又兩種方案去處理請(qǐng)求:

  • app.get/post/use …

  • express.Router().get/post …

  • app.route(路徑).get/post()

同一個(gè)請(qǐng)求路徑使用不同的請(qǐng)求方法多次請(qǐng)求的簡(jiǎn)寫(xiě):

app.route('/book')
  .get(function(req, res) {
    res.send('Get a random book');
  })
  .post(function(req, res) {
    res.send('Add a book');
  })
  .put(function(req, res) {
    res.send('Update the book');
  });

中間件

中間件(middleware)可以理解為業(yè)務(wù)流程的中間處理環(huán)節(jié),可以理解成中間過(guò)濾器。

express怎么使用

中間件的分類

中間件可以分類可分如下幾類:

  • 內(nèi)置中間件,也就是express本身自帶無(wú)需npm安裝

    • express.static()

  • 第三方中間件

    非 Express 官方內(nèi)置的,而是由第三方開(kāi)發(fā)出來(lái)的中間件,叫做第三方中間件。在項(xiàng)目中可以通過(guò)npm進(jìn)行安裝第三方中間件并配置,從而提高項(xiàng)目的開(kāi)發(fā)效率。例如body-parser (解析post數(shù)據(jù)的)此中間件可以很方便幫助我們獲取到post提交過(guò)來(lái)的數(shù)據(jù)。

  • 自定義中間件,開(kāi)發(fā)者自己編寫(xiě)的(中間件的本質(zhì)其實(shí)就是一個(gè)function

如果從使用層面去考慮,中間件可以劃分為:

  • 應(yīng)用級(jí)別中間件(通過(guò)app.get/post/use等方法綁定到app實(shí)例的中間件)

    • app.請(qǐng)求方法(地址,[中間件…,]回調(diào)函數(shù))

    • app.請(qǐng)求方法(地址,中間件1,中間2,中間3…,]回調(diào)函數(shù))

    • app.use(中間件)

    • 全局使用中間件(所有路由都生效)

    • 局部使用中間件(當(dāng)前路由生效)

  • 路由級(jí)別中間件(綁定到express.Router()上的中間件)

    • router.use(中間件)

    • router.請(qǐng)求方法(地址,[中間件…,]回調(diào)函數(shù))

    • 其用法與應(yīng)用級(jí)別的中間件沒(méi)有任何區(qū)別,只是一個(gè)綁在app實(shí)例上,一個(gè)綁在router上

內(nèi)置中間件

express提供了好用的內(nèi)置中間件,如提供一個(gè)靜態(tài)資源管理的中間件,通過(guò)此中間件就可以幫助為我們快速搭建一個(gè)靜態(tài)資源服務(wù)器:

app.use('前綴',express.static('托管目錄地址'))

在express中,除了內(nèi)置的express.static()中間件,還內(nèi)置了另外2個(gè)常用的中間件:

  • express.json()

    使用示例:

    // 有了這個(gè)中間件以后,我們可以從客戶端給服務(wù)器端發(fā)送json數(shù)據(jù),這個(gè)json數(shù)據(jù)會(huì)放到請(qǐng)求對(duì)象req的body屬性上app.use(express.json())app.post('/p1',(req,res)=>{
        // express.json中間件可以讓數(shù)據(jù)掛在req的body屬性上
        console.log(req.body);
        res.send('this p1 request is ended')})

    首先必須是post請(qǐng)求,然后必須有數(shù)據(jù),但是數(shù)據(jù)不能是以前的 x-www-form-urlencoded這樣的數(shù)據(jù),必須是raw的數(shù)據(jù)

    然后請(qǐng)求頭的content-type 必須是 application/json

    • 作用:接收json格式提交的數(shù)據(jù)

    • 兼容性問(wèn)題:express >= 4.16.0

    • app.use(express.json())

    • 其在接收完數(shù)據(jù)后,會(huì)將數(shù)據(jù)的對(duì)象形式掛載到req請(qǐng)求對(duì)象的body屬性上

  • express.urlencoded()

    • 作用:處理post表單數(shù)據(jù)

    • 兼容性問(wèn)題:express >= 4.16.0

    • app.use(express.urlencoded({extended: false}))

    • 其在接收完數(shù)據(jù)后,會(huì)將數(shù)據(jù)的對(duì)象形式掛載到req請(qǐng)求對(duì)象的body屬性上

注意,

  • 后面提及的這2個(gè)常用內(nèi)置中間件存在兼容性問(wèn)題。

  • 上述2個(gè)中間件都說(shuō)把數(shù)據(jù)處理之后掛到req.body上,但是實(shí)際上并不會(huì)出現(xiàn)我們想的覆蓋的問(wèn)題。

案例:使用json、urlencoded中間件來(lái)接收json數(shù)據(jù)與表單post數(shù)據(jù),發(fā)送可以通過(guò)postman來(lái)進(jìn)行

自定義中間件

自定義中間件,其本質(zhì)就是定義一個(gè)處理請(qǐng)求的函數(shù),只是此函數(shù)中除了有request和response參數(shù)外還必須包含一個(gè)next參數(shù),此參數(shù)作用讓中間件能夠讓流程向下執(zhí)行下去直到匹配到的路由中發(fā)送響應(yīng)給客戶端。也可以通過(guò)給request對(duì)象添加屬性來(lái)進(jìn)行中間件數(shù)據(jù)的向下傳遞

function mfn(req,res,next){	
    //. 自己需要定義的邏輯流程
	// 中間件最后一定要執(zhí)行此函數(shù),否則程序無(wú)法向下執(zhí)行下去
	next()}

注意:在整個(gè)請(qǐng)求鏈路中,所有中間件與最終路由共用一份reqres

express怎么使用

案例:依據(jù)上述的共用特性,自定義一個(gè)中間件來(lái)接收post提交的表單數(shù)據(jù)(意義:內(nèi)置那中間件是不是存在兼容性問(wèn)題)

第三方中間件

在express中,其允許我們使用第三方的中間件來(lái)進(jìn)行對(duì)數(shù)據(jù)進(jìn)行處理。比較典型的例如:可以使用第三方中間件來(lái)接收post數(shù)據(jù)。

以使用body-parser中間件來(lái)接收post數(shù)據(jù)為例,步驟如下:

  • 安裝三方中間件body-parser

    • npm i -S body-parser

  • 應(yīng)用文件中導(dǎo)入body-parser

  • 通過(guò)中間件調(diào)用 app.use(body.urlencoded({extended: false}))

  • 在匹配的路由中通過(guò)req.body獲數(shù)post中數(shù)據(jù)

    • Express內(nèi)置的express.urlencoded中間件,就是基于body-parser這個(gè)第三方中間件進(jìn)一步封裝出來(lái)的。但內(nèi)置的有版本兼容問(wèn)題,所以一般項(xiàng)目選擇安裝使用第三方的中間件

在使用的時(shí)候,body-parser庫(kù)的語(yǔ)法與前面看的express內(nèi)置的express.urlencoded中間件的語(yǔ)法非常相似,原因是內(nèi)置中間件是基于body-parser來(lái)實(shí)現(xiàn)的。

其他第三方中間件:http-proxy-middleware/cors/cookie-session …

異常處理中間件

**作用:**專門用來(lái)捕獲整個(gè)項(xiàng)目發(fā)生的異常錯(cuò)誤,從而防止項(xiàng)目異常崩潰的問(wèn)題產(chǎn)生(友好顯示異常)。

**格式:**錯(cuò)誤級(jí)別中間件的函數(shù)參數(shù)中,必須有四個(gè)形參,分別是(err,req,res,next)

問(wèn):多出來(lái)的err參數(shù)有什么作用呢?

答:里面包含了錯(cuò)誤的信息,err.message屬性中就包含了錯(cuò)誤的文本信息,這個(gè)信息可以在中間件中輸出給用戶看。

app.get('/',(req,res) => {
    throw new Error('服務(wù)器內(nèi)部發(fā)生了致命的錯(cuò)誤!')
    res.send('Welcome to my homepage')})app.use((err,req,res,next) => {
    console.log('發(fā)生了錯(cuò)誤:' + err.message)
    res.send('Error!' + err.message)})

**案例:**要求指定一個(gè)路徑(可能路由對(duì)應(yīng)的文件不存在),讀取文件內(nèi)容,輸出給用戶

注意事項(xiàng):錯(cuò)誤級(jí)別中間件要想發(fā)揮其作用,必須寫(xiě)在所有的路由的后面,是否是app.listen之前無(wú)所謂。

404中間件

**作用:**用于處理404的請(qǐng)求響應(yīng)

// 假設(shè)定義這個(gè)路由,但是實(shí)際請(qǐng)求的時(shí)候請(qǐng)求了/12345,這個(gè)時(shí)候就會(huì)404app.post("/1234", (req, res, next) => {
    res.send('你請(qǐng)求成功了')});// 404的輸出// 該中間件也需要寫(xiě)在最后(與異常中間件的順序無(wú)所謂,只要確保其在所有的路由方法之后就可)app.use((req,res,next) => {
    // 輸出404錯(cuò)誤
    res.status(404).send('<h2>404</h2>')
    // 先指定404狀態(tài)碼,然后再輸出錯(cuò)誤信息})

404錯(cuò)誤中間件也要求在所有的正常請(qǐng)求路由的后面去聲明使用,不要放在路由的前面,否則會(huì)導(dǎo)致后面的路由都是404錯(cuò)誤。

**注意點(diǎn):**錯(cuò)誤級(jí)別的中間件,必須在所有路由之后注冊(cè),至于404中間件與異常中間件,誰(shuí)先誰(shuí)后無(wú)所謂。

模板頁(yè)面:頁(yè)面:https://404.life/

其他模塊

cookie

cookie的原理是在瀏覽器中開(kāi)辟了一個(gè)用來(lái)存儲(chǔ)http請(qǐng)求中的數(shù)據(jù),第一次保存之后,下次請(qǐng)求只要還是使用的當(dāng)前瀏覽器,就能訪問(wèn)到瀏覽器這個(gè)空間中的數(shù)據(jù)。

cookie會(huì)作為鍵值對(duì),在響應(yīng)頭和請(qǐng)求頭之間攜帶。

cookie的特點(diǎn):

  1. 域名限制,當(dāng)前域名下設(shè)置的cookie,只能在當(dāng)前域名下使用

  2. 時(shí)效性,cookie不會(huì)永久存儲(chǔ)在瀏覽器,具有一定的有效期

  3. 數(shù)量限制,正常情況下,每個(gè)域名最多不能超過(guò)50個(gè)cookie

  4. 空間限制,cookie只能存儲(chǔ)4kb

  5. 數(shù)據(jù)類型限制,cookie中只能存儲(chǔ)字符串

npm i cookie-parser -S

使用:

// 導(dǎo)入
const cookieParser = require('cookie-parser')
// 中間件
app.use(cookieParser());
// 請(qǐng)求頭獲取
req.headers.cookie // 獲取所有cookie
// 響應(yīng)頭設(shè)置
res.cookie(鍵,值,{maxAge: 有效期-毫秒}) // 設(shè)置cookie

session

cookie是存儲(chǔ)在瀏覽器的,所以安全性不高,所以一些重要數(shù)據(jù)就不能存儲(chǔ)在cookie中,且cookie的存儲(chǔ)空間有限制,所以就有了session。

session是存儲(chǔ)服務(wù)器端的,session需要依賴cookie,session數(shù)據(jù)存儲(chǔ)會(huì)在cookie中存放一個(gè)sessionid,這個(gè)sessionid會(huì)跟服務(wù)器端之間產(chǎn)生映射關(guān)系,如果sessionid被篡改,他將不會(huì)跟服務(wù)器端進(jìn)行隱射,因此安全系數(shù)更高。且session的有效期比較短。通常是20分鐘左右,如果瀏覽器在20分鐘內(nèi)沒(méi)有跟服務(wù)器進(jìn)行交互,服務(wù)器就會(huì)刪除session數(shù)據(jù)。

npm i cookie-session -S

使用:

// 導(dǎo)入:const session = require('cookie-session')// session配置session({
    name:"sessionId",
    secret:"asdfasdfqwer", // 給sessioinId加密使用的秘鑰,隨便填寫(xiě)
    maxAge:20*60*1000 // 20分鐘})// 設(shè)置sessionreq.session[鍵] = 值// 獲取sessionreq.session[鍵]

加密

npm i bcryptjs -S

使用:

var bcrypt = require('bcryptjs');
// 加密
密文 = bcryptjs.hashSync(明文[,數(shù)字]); // 數(shù)字,將使用指定的輪數(shù)生成鹽并將其使用。推薦 10
// 驗(yàn)證
bcryptjs.compareSync(明文,密文); // 通過(guò)返回true,失敗返回false

jwt

npm install jsonwebtoken

使用:

// 加密生成tokenvar jwt = require('jsonwebtoken');var token = jwt.sign(被加密的對(duì)象, 鹽);// 驗(yàn)證jwt.verify(token, 鹽, function(err, decoded) {
  // decoded是解密后的對(duì)象});

文件上傳

npm i multer -S

使用:

var multer  = require('multer')var upload = multer({ dest: path.join(__dirname,'public','image') }) // 指定上傳的文件路徑app.post('/profile', upload.single('上傳表單name值'), function (req, res, next) {
  // req.file 是上傳的文件信息 - 可以從中獲取到文件名稱、路徑、后綴 - 拼接路徑存入mongodb})

mysql

npm i mysql -S

使用:

// 導(dǎo)入const mysql = require("mysql");// 創(chuàng)建連接對(duì)象const db = mysql.createConnection({
    host:"localhost",
    user:"root",
    password:"root",
    database:"test"});// 連接db.connect(err=>{
    if(err){
        console.log("連接失敗,錯(cuò)誤:"+err);
        return;
    }
    console.log("連接成功");});// 執(zhí)行語(yǔ)句db.query("",(err,result)=>{
    if(err){
        console.log("失敗,錯(cuò)誤:"+err);
        return;
    }
    console.log("成功");
    console.log(result);});

驗(yàn)證碼

npm i svg-captcha -S

使用:

const svgCaptcha = require('svg-captcha')
// 創(chuàng)建驗(yàn)證碼
let captcha = svgCaptcha.create();
// captcha是是一個(gè)對(duì)象,其中包含data鍵和text鍵,text是驗(yàn)證碼上的字符,data是一個(gè)svg標(biāo)簽直接可以顯示為一張圖片

郵件發(fā)送

npm install nodemailer --save

使用:

const nodemailer = require('nodemailer')// 1. 創(chuàng)建發(fā)送器const transport = nodemailer.createTransport({
  // 需要你發(fā)送放郵箱的 stmp 域名和密碼和一些其他信息
  // 需要你去復(fù)制一下, 找到下載的 nodemailer 第三方包
  //   nodemailer -> lib -> well-known -> services.json
  "host": "smtp.qq.com",
  "port": 465,
  "secure": true,
  // 證明你的身份
  auth: {
    // 發(fā)送方郵箱的用戶名
    user: '郵箱號(hào)',
    // stmp 允許密碼
    pass: '授權(quán)碼'
  }})// 2. 發(fā)送郵件transport.sendMail({
  // 從那個(gè)郵箱發(fā)送
  from: '發(fā)送方郵箱',
  // 發(fā)送到哪里, 可以寫(xiě)一個(gè)字符串, 書(shū)寫(xiě)郵箱, 也可以寫(xiě)一個(gè)數(shù)組, 寫(xiě)好多郵箱
  to: ['接收方郵箱', '接收方郵箱'],
  // 郵件標(biāo)題
  subject: '標(biāo)題',
  // 本次郵件的 超文本 內(nèi)容
  html: `
    您好: 本次的驗(yàn)證碼是
    <h2 style="color: red;"> 2345 </h2>
    請(qǐng)?jiān)?nbsp;3 分鐘內(nèi)使用


    <br>
    ------------------------<br>
    前途無(wú)限股份有限公司
  `,
  // 本次郵件的 文本 內(nèi)容
  // text: ''}, function (err, data) {
  if (err) return console.log(err)

  console.log('郵件發(fā)送成功')
  console.log(data)})

模板引擎

介紹

在一個(gè)web應(yīng)用程序中,如果只是使用服務(wù)器端代碼來(lái)編寫(xiě)客戶端html代碼,前后端不分離,那么會(huì)造成很大的工作量,而且寫(xiě)出來(lái)的代碼會(huì)比較難以閱讀和維護(hù)。如果只是使用客戶端的靜態(tài)的HTML文件,那么后端的邏輯也會(huì)比較難以融入到客戶端的HTML代碼中。為了便于維護(hù),且使后端邏輯能夠比較好的融入前端的HTML代碼中,同時(shí)便于維護(hù),很多第三方開(kāi)發(fā)者就開(kāi)發(fā)出了各種Nodejs模板引擎,其中比較常用的就是Jade/Pug、Ejs和art-template 等模板引擎。

目的:使后端邏輯能夠比較好的融入前端的HTML代碼中,同時(shí)便于維護(hù)

art-template 是一個(gè)簡(jiǎn)約、超快的模板引擎。

開(kāi)發(fā)模式:
傳統(tǒng)開(kāi)發(fā)模式:
前端代碼和后端代碼寫(xiě)在了一起
混合在了一起,但是這種文件有要求,文件通常都是后端語(yǔ)言的文件中才能寫(xiě)后端的邏輯 - 這樣的話,對(duì)于我們前端攻城獅特別不友好,因?yàn)槲覀兦岸斯コ仟{負(fù)責(zé)html頁(yè)面,但是在html頁(yè)面中不能寫(xiě)后端的邏輯,如果將html頁(yè)面放在后端的文件中,我們又需要學(xué)習(xí)后端語(yǔ)言
此時(shí),模板引擎出現(xiàn)了 - 模板引擎其實(shí)就是讓我們可以在html頁(yè)面中書(shū)寫(xiě)后端的邏輯 - 循環(huán)/判斷 …
模板引擎有很多種:jade/ejs/art-tamplate …

模板引擎最終能在html中寫(xiě)邏輯,相當(dāng)于我們代碼前后端混合在一起的一種語(yǔ)法,最終為什么能被瀏覽器所識(shí)別?因?yàn)闉g覽器在識(shí)別之前,我們的模板引擎需要進(jìn)行編譯 - html代碼
前后端分離開(kāi)發(fā)模式:
html一個(gè)人去寫(xiě);
后端接口另一個(gè)人去寫(xiě);
雙方之間對(duì)接,使用接口文檔
html上所有的數(shù)據(jù),都是通過(guò)ajax請(qǐng)求回來(lái),并通過(guò)dom操作顯示在頁(yè)面中的

模板引擎渲染速度測(cè)試:
express怎么使用

特性

  • 擁有接近 JavaScript 渲染(DOM操作)極限的的性能(快)

  • 調(diào)試友好:語(yǔ)法、運(yùn)行時(shí)錯(cuò)誤日志精確到模板所在行;支持在模板文件上打斷點(diǎn)(Webpack Loader)

  • 支持 Express、Koa、Webpack

  • 支持模板繼承(布局)與子模板(引入包含)

  • 瀏覽器版本僅 6KB 大小

使用

下載安裝:

# 安裝
npm i -S art-template express-art-template

配置:

// 模板引擎配置
// 指定art-template模板,并指定模塊后綴為.html
app.engine('html', require('express-art-template'));
// 指定模板視圖路徑
app.set('views', path.join(__dirname, 'views'));
// 省略指定模塊文件后綴后名稱(可選,在渲染時(shí)可以省略的后綴)
app.set('view engine', 'html')	

art-template 支持**標(biāo)準(zhǔn)語(yǔ)法原始語(yǔ)法**。標(biāo)準(zhǔn)語(yǔ)法可以讓模板易讀寫(xiě),而原始語(yǔ)法擁有強(qiáng)大的邏輯表達(dá)能力。標(biāo)準(zhǔn)語(yǔ)法支持基本模板語(yǔ)法以及基本 JavaScript 表達(dá)式;原始語(yǔ)法支持任意 JavaScript 語(yǔ)句,這和 Ejs一樣。

  • 使用art-template展示一個(gè)視圖(html文件)

    • 將視圖放入views目錄下(允許分目錄)

    • 編寫(xiě)代碼,展示視圖的方式是`res.redner(文件的路徑)

      app.get('/', (req, res) => {
          // 輸出視圖
          res.render('404.html')})
  • 控制層返回?cái)?shù)據(jù)(在js控制層中賦值變量到視圖中)

    app.get(uri,(req,res)=>{
    	res.render(模板,{
    		username: '張三',
            age: 25,
            gender: '女',
            hobby: ['籃球','乒乓球','羽毛球']
    	})})

模板語(yǔ)法

變量輸出:

<!-- 標(biāo)準(zhǔn)語(yǔ)法 -->{{ username }}<!-- 或者 --><!-- 原始語(yǔ)法 --><%= username %>

在默認(rèn)情況下,上述輸出方式不能將帶有HTML標(biāo)記的內(nèi)容讓瀏覽器解析,只會(huì)原樣輸出。如果需要將HTML標(biāo)記讓瀏覽器,則請(qǐng)使用下述方式輸出數(shù)據(jù):

<!-- 標(biāo)準(zhǔn)語(yǔ)法 -->{{@ username}}<!-- 原始語(yǔ)法 --><%- username %>

條件判斷:

{{if 條件}} … {{else if 條件}} … {{/if}}
<%if (條件){%> … <%}else if (條件){%> … <%}%>

循環(huán):

<!-- 支持 數(shù)組和對(duì)象的迭代  默認(rèn)元素變量為$value 下標(biāo)為$index  可以自定義 {{each target val key}}-->{{each 循環(huán)的數(shù)據(jù)}}
    {{$index}} {{$value}}
{{/each}}

{{each 循環(huán)的數(shù)據(jù) val key}}
    {{key}} {{val}}
{{/each}}

<% for(var i = 0; i < target.length; i++){ %>
    <%= i %> <%= target[i] %>
<% } %>

如果使用默認(rèn)的鍵、值的名字(index,value)則其前面的$一定要寫(xiě)!一定要寫(xiě)?。?!

如果使用的自定義的鍵、值的名字,則前面的$一定不能寫(xiě)?。〔荒軐?xiě)?。?/p>

模板導(dǎo)入:

{{include '被引入文件路徑'}}
<% include('被引入文件路徑') %>
  • 如果是當(dāng)前路徑下的一定要寫(xiě)./,不寫(xiě)則從磁盤(pán)根下開(kāi)始尋找

  • 被include的文件后綴名默認(rèn)為.art,如果不是請(qǐng)勿省略

  • 在子模板中最好不要有html、head和body標(biāo)簽(否則容易出現(xiàn)樣式錯(cuò)誤的問(wèn)題)

模板繼承:

被繼承的模板:

<html><head>
    <meta charset="utf-8">
    <!-- 類似于vue的插槽 -->
    <title>{{block 'title'}}My Site{{/block}}</title></head><body>
	<!-- block占位符 content此占位的名稱 -->
    {{block 'content'}}{{/block}}</body></html>

需要繼承的子模板:

<!--extend 繼承 -->{{extend './layout.html'}}
{{block 'title'}}首頁(yè){{/block}}
{{block 'content'}}	<p>This is just an awesome page.</p>{{/block}}

關(guān)于“express怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI