欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長(zhǎng)資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          總結(jié)Node.js模塊開(kāi)發(fā)及常用技巧分享

          一、模塊化

          模塊化做為一種現(xiàn)代化的設(shè)計(jì)方法,這個(gè)概念最早起源于生產(chǎn)制造行業(yè)。如今這個(gè)概念已經(jīng)被各行各業(yè)來(lái)衍生應(yīng)用,在軟件開(kāi)發(fā)中也大量的采用了模塊化思想。

          所謂的模塊化思想,將一個(gè)大程序按照功能劃分為若干個(gè)小的模塊,每個(gè)小程序模塊完成一個(gè)特定的功能,所有的模塊按某種方法組裝起來(lái),成為一個(gè)整體,完成整個(gè)系統(tǒng)所要求功能的程序設(shè)計(jì)方法。【推薦:node.js視頻教程】

          (一)、為什么需要模塊化

          模塊化可以使你的代碼低耦合,功能模塊直接不相互影響。

          為什么需要模塊化:

          • 程序復(fù)雜度上升代碼越寫(xiě)越多,在一個(gè)文件里代碼就會(huì)越來(lái)越長(zhǎng),不易維護(hù)。(把完成特定功能的代碼分組,分別放到不同的文件里,這樣,每個(gè)文件包含的代碼就相對(duì)較少)

          • JavaScript 有復(fù)雜的依賴(lài)關(guān)系的時(shí)候就很容易出現(xiàn)一些變量的屬性或方法被覆蓋或改寫(xiě),導(dǎo)致變量污染。這是因?yàn)閖s沒(méi)有命名空間,不像其他語(yǔ)言通過(guò)命名空間可以有效的避免重名問(wèn)題。

          • 想要存在JavaScript 私有的變量

          模塊化思想解決問(wèn)題:

          • 可維護(hù)性:每個(gè)模塊都是單獨(dú)定義的,之間相互獨(dú)立。模塊盡可能的需要和外部撇清關(guān)系,方便我們獨(dú)立的對(duì)其進(jìn)行維護(hù)與改造。維護(hù)一個(gè)模塊比在全局中修改邏輯判斷要好的多。

          • 命名沖突:為了避免在JavaScript中的全局污染,我們通過(guò)模塊化的方式利用函數(shù)作用域來(lái)構(gòu)建命名空間,避免命名沖突。

          • 文件依賴(lài):一個(gè)功能可能依賴(lài)一個(gè)或多個(gè)其他文件,使用是除了引入它本身還需要考慮依賴(lài)文件,通過(guò)模塊化 我們只需要引入文件,無(wú)需考慮文件依賴(lài)(模塊化可以幫助我們解決文件依賴(lài)問(wèn)題)。

          • 可復(fù)用性:雖然粘貼復(fù)制很簡(jiǎn)單,但是要考慮到我們之后的維護(hù)以及迭代。

          (二)、什么是Nodejs模塊

          為了讓Nodejs的文件可以相互調(diào)用,Nodejs基于CommonJS規(guī)范提供了一個(gè)簡(jiǎn)單的模塊系統(tǒng)。(nodejs實(shí)現(xiàn)并遵守CommonJS規(guī)范的)。

          把具有公共功能的,抽離成一個(gè)單獨(dú)的js文件作位一個(gè)模塊。默認(rèn)情況下,模塊里的方法或?qū)傩?,外面是訪問(wèn)不到的。如果想要在外面訪問(wèn)這些屬性,方法,就必須在模塊里通過(guò)exportsmodule.exports暴露,在需要使用的地方通過(guò)require()進(jìn)行引入。

          //exports語(yǔ)法示例  // sum.js exports.sum = function(a,b){     return a+b; }  // main.js var m = require("./sum"); var num = m.sum(10,20); console.log(num);  //modules.exports語(yǔ)法示例  //sum.js function sum(a,b){     return a+b; } module.exports= sum; //main.js var sum = require('./sum'); sum(10,20);// 30

          CommonJS 規(guī)定:

          • 每個(gè)模塊內(nèi)部,module 變量代表當(dāng)前模塊

          • module 變量是一個(gè)對(duì)象,它的 exports 屬性(即 module.exports)是對(duì)外的接口

          • 加載某個(gè)模塊,其實(shí)是加載該模塊的 module.exports 屬性。require() 方法用于加載模塊。

          (三)、nodejs中的模塊分類(lèi)與加載方式

          Node.js 中根據(jù)模塊來(lái)源的不同,將模塊分為了 3 大類(lèi),分別是:

          • 內(nèi)置模塊(內(nèi)置模塊是由 Node.js 官方提供的,例如 fs、path、http 等)

          • 自定義模塊(用戶(hù)創(chuàng)建的每個(gè) .js 文件,都是自定義模塊)

          • 第三方模塊(包)(由第三方開(kāi)發(fā)出來(lái)的模塊,并非官方提供的內(nèi)置模塊,也不是用戶(hù)創(chuàng)建的自定義模塊,使用前需要先下載)

          //1.加載內(nèi)置模塊不需要指定路徑 var http = require('http');  //2.加載用戶(hù)的自定義模塊 var sum = require('./sum.js');  //3.加載第三方模塊 const md5=require("md5");

          (四)、模塊作用域

          • 和函數(shù)作用域類(lèi)似,在自定義模塊中定義的變量、方法等成員,只能在當(dāng)前模塊內(nèi)被訪問(wèn),這種模塊級(jí)別的訪問(wèn)限制,叫做模塊作用域。
          • 模塊作用域的好處:防止了全局變量污染的問(wèn)題

          二、npm與包

          (一)、包的介紹

          • Node.js 中的第三方模塊又叫做包。包是由第三方個(gè)人或團(tuán)隊(duì)開(kāi)發(fā)出來(lái)的,免費(fèi)供所有人使用。
          • Node.js 的內(nèi)置模塊僅提供了一些底層的 API,導(dǎo)致在基于內(nèi)置模塊進(jìn)行項(xiàng)目開(kāi)發(fā)的時(shí),效率很低。
            包是基于內(nèi)置模塊封裝出來(lái)的,提供了更高級(jí)、更方便的 API,極大的提高了開(kāi)發(fā)效率。
          • 國(guó)外有一家 IT 公司,叫做 npm, Inc. 這家公司旗下有一個(gè)非常著名的網(wǎng)站: https://www.npmjs.com/ ,它是全球最大的包共享平臺(tái)。
          • 我們可以使用這個(gè)包管理工具, npm ,來(lái)對(duì)包進(jìn)行管理,這個(gè)包管理工具隨著 Node.js 的安裝包一起被安裝到了用戶(hù)的電腦上。檢測(cè)其版本。npm -v

          (二)、npm的使用

          • npm init 進(jìn)行初始化,生成package.json 文件,記錄項(xiàng)目的信息,記錄包的信息
          • npm install 包名 npm i 包名 下載包,放到node_modules文件夾里
          • npm i 包名 --save npm i 包名 -S (開(kāi)發(fā)環(huán)境中)
          • npm i 包名 --save-dev npm i 包名 -D (生產(chǎn)環(huán)境中)
          • npm list 列舉當(dāng)前目錄下安裝的包
          • npm i 包名@1 安裝指定的版本
          • npm i 包名 -g 安裝全局包
          • npm uninstall 包名 卸載包

          (三)、全局安裝nrm nodemon

          nrm 是一個(gè)管理 npm 源的工具。有時(shí)候國(guó)外資源太慢,使用這個(gè)就可以快速的在npm源間切換。

          手動(dòng)切換方法:

          npm config set registry=https://registry.npm.taobao.org

          安裝 nrm:

          $ npm i nrm -g

          查看nrm 內(nèi)置的幾個(gè) npm 源的地址:

          $ nrm ls

          結(jié)果如下:

            npm ---- https://registry.npmjs.org/   cnpm --- http://r.cnpmjs.org/ * taobao - https://registry.npm.taobao.org/   nj ----- https://registry.nodejitsu.com/   rednpm - http://registry.mirror.cqupt.edu.cn/   npmMirror  https://skimdb.npmjs.com/registry/   edunpm - http://registry.enpmjs.org/

          切換nrm:

          $ nrm use npm

          查看當(dāng)前的鏡像源:

          npm config get register

          (四)、淘寶cnpm工具

          淘寶 NPM 鏡像是一個(gè)完整 npmjs.org 鏡像,你可以用此代替官方版本(只讀),同步頻率目前為 10分鐘 一次以保證盡量與官方服務(wù)同步。

          你可以使用淘寶定制的 cnpm (gzip 壓縮支持) 命令行工具代替默認(rèn)的 npm:

          npm install -g cnpm -registry=https://registry.npm.taobao.org

          安裝包

          cnpm install [模塊名]

          三、路由

          路由:根據(jù)不同的路徑返回不同的頁(yè)面。

          案例:server.js;static;route.js;route對(duì)象;render();api.js;封裝server.js到index.js;合并對(duì)象

          獲取請(qǐng)求參數(shù):login頁(yè)面發(fā)get,post請(qǐng)求,到/api/login

          靜態(tài)資源托管:

          express

          Express是一個(gè)基于 Node.js 平臺(tái),快速、開(kāi)放、極簡(jiǎn)的 Web 開(kāi)發(fā)框架。

          一、下載與安裝

          $ npm install express --save

          案例:第一個(gè)express案例。

          二、路由

          所謂的路由就是客戶(hù)端用來(lái)與后端服務(wù)器進(jìn)行交互的一種方式,客戶(hù)端采用特定的URL與請(qǐng)求方法來(lái)訪問(wèn)服務(wù)器端,服務(wù)器端通過(guò)響應(yīng)返回特定資源。

          路由的定義由如下結(jié)構(gòu)組成:

          app.METHOD(PATH, HANDLER)
          名稱(chēng) 描述
          app app 是一個(gè) express 實(shí)例
          METHOD METHOD用于指定要匹配的HTTP請(qǐng)求方式
          PATH PATH是服務(wù)器端的路徑
          HANDLER 是當(dāng)路由匹配時(shí)需要執(zhí)行的處理程序(回調(diào)函數(shù))

          路由路徑和請(qǐng)求方法一起定義了請(qǐng)求的端點(diǎn),它可以是字符串,字符串模式以及正則表達(dá)式。

          app.get('/', function (req, res) {   res.send('root')})app.get('/about', function (req, res) {   res.send('about')})app.get('/random.text', function (req, res) {   res.send('random.text')})

          使用字符串模式的路由路徑示例:

          app.get('/ab?cd', function (req, res) {   res.send('ab?cd')  //abcd ,acd})app.get('/ab/:id', function (req, res) {   res.send('ab/:id')  })app.get('/ab+cd', function (req, res) {   res.send('ab+cd')    //b可以一次或者多次的重復(fù)})app.get('/ab*cd', function (req, res) {   res.send('ab*cd')  //在ab,cd之間隨意寫(xiě)入任意字符})app.get('/ab(cd)?e', function (req, res) {   res.send('ab(cd)?e')})

          可以為請(qǐng)求處理提供多個(gè)回調(diào)函數(shù),其行為類(lèi)似中間件。

          案例:中間件f1,f2

          app.get('/example/b', function (req, res, next) {   console.log('the response will be sent by the next function ...')   next()}, function (req, res) {   res.send('Hello from B!')})
          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])
          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('the response will be sent by the next function ...')   next()}, function (req, res) {   res.send('Hello from D!')})

          三、中間件

          1.應(yīng)用級(jí)中間件

          在Express程序中,使用 app.use()app.METHOD() 方法將中間件綁定到應(yīng)用程序?qū)ο?app)。

          凡是掛載在app身上的都是應(yīng)用級(jí)中間件。

          app.use() : 應(yīng)用中的每個(gè)請(qǐng)求都可以執(zhí)行其代碼

          //萬(wàn)能中間件var express = require('express')var app = express()app.use(function (req, res, next) {     console.log('Time:', Date.now())     next()})
          //特定路由的應(yīng)用中間件app.use("/login",function (req, res, next) {     console.log('Time:', Date.now())})

          2.路由級(jí)中間件

          路由器級(jí)中間件的工作方式與應(yīng)用級(jí)中間件相同,只是它綁定到express.Router().

          var router = express.Router()
          var express = require('express')var app = express()var router = express.Router()router.use(function (req, res, next) {     console.log('Time:', Date.now())     next()})router.get('/user/:id', function (req, res, next) {     console.log('Request URL:', req.originalUrl)     next()}, function (req, res, next) {     console.log('Request Type:', req.method)     next()})

          案例: / ; /home , /list

          3.錯(cuò)誤處理中間件

          與其他中間件函數(shù)相同的方式定義錯(cuò)誤處理中間件函數(shù),但是使用四個(gè)參數(shù)(err, req, res, next),放到最后。

          app.use(function (err, req, res, next) {   console.error(err.stack)   res.status(404).send('Something broke!')})

          4.內(nèi)置中間件

          • express.static提供靜態(tài)資源,例如 HTML 文件、圖像等。

          • express.json使用 JSON 有效負(fù)載解析傳入請(qǐng)求。注意:可用于 Express 4.16.0+

            application/json

            由于JSON規(guī)范的流行,現(xiàn)在越來(lái)越多的開(kāi)發(fā)者將application/json這個(gè)Content-Type作為響應(yīng)頭。用來(lái)告訴服務(wù)端消息主體是序列化后的JSON字符串。除了低版本IE之外各大瀏覽器都原生支持 JSON.stringify,服務(wù)端語(yǔ)言也都有處理JSON的函數(shù),JSON能格式支持比鍵值對(duì)復(fù)雜得多的結(jié)構(gòu)化數(shù)據(jù),普通鍵值對(duì)中的值只能是字符串,而使用json,鍵值對(duì)可以重復(fù)嵌套。

            // 應(yīng)用級(jí)別中間件,獲取post--json參數(shù)app.use(express.json());
          • express.urlencoded解析帶有 URL 編碼負(fù)載的傳入請(qǐng)求。 注意:可用于 Express 4.16.0+

            application/x-www-form-urlencoded
            瀏覽器的原生form表單,如果不設(shè)置enctype屬性,那么最終就會(huì)以 application/x-www-form-urlencoded方式提交數(shù)據(jù)。Content-Type被指定為application/x-www-form-urlencoded提交的數(shù)據(jù)按照key=val&key=val的方式進(jìn)行編碼,并且key和val都進(jìn)行了URL轉(zhuǎn)碼。

            // 應(yīng)用級(jí)別中間件,獲取post--form參數(shù)app.use(express.urlencoded({extended:false}));

          5.第三方中間件

          四、獲取請(qǐng)求參數(shù)

          • req.query 是一個(gè)可獲取客戶(hù)端get請(qǐng)求 查詢(xún)字符串 轉(zhuǎn)成的對(duì)象,默認(rèn)為{}。
          • req.body 包含在請(qǐng)求體中提交的數(shù)據(jù)鍵值對(duì)。默認(rèn)情況下undefined,當(dāng)使用解析中間件express.json()、express.urlencoded()

          五、靜態(tài)資源托管

          為了提供諸如圖像、CSS 文件和 JavaScript 文件之類(lèi)的靜態(tài)文件,請(qǐng)使用 Express 中的 express.static 內(nèi)置中間件函數(shù)。

          語(yǔ)法:

          express.static內(nèi)置中間件函數(shù)語(yǔ)法:

          express.static(root, [options])
          • root參數(shù)指定提供靜態(tài)資源的根目錄。

          靜態(tài)資源示例:

          例如,通過(guò)如下代碼就可以將 public 目錄下的圖片、CSS 文件、JavaScript 文件對(duì)外開(kāi)放訪問(wèn)了:

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

          現(xiàn)在,你就可以訪問(wèn) public 目錄中的所有文件了:

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

          Express 在靜態(tài)目錄查找文件,因此,存放靜態(tài)文件的目錄名不會(huì)出現(xiàn)在 URL 中。

          多個(gè)靜態(tài)資源目錄:

          如果要使用多個(gè)靜態(tài)資源目錄,請(qǐng)多次調(diào)用 express.static 中間件函數(shù):

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

          訪問(wèn)靜態(tài)資源文件時(shí),express.static 中間件函數(shù)會(huì)根據(jù)目錄的添加順序查找所需的文件。

          虛擬路徑:(非得添加static,沒(méi)有意義)

          express.static中間件函數(shù)可以為某些靜態(tài)資源服務(wù)創(chuàng)建虛擬路徑前綴(該路徑實(shí)際上并不存在于文件系統(tǒng)中),請(qǐng)指定靜態(tài)目錄的掛載路徑,如下所示:

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

          現(xiàn)在,你就可以通過(guò)帶有 /static 前綴地址來(lái)訪問(wèn) 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

          六、模板引擎

          一、.服務(wù)端渲染 SSR

          后端嵌套模板,后端渲染模板 (后端把頁(yè)面組裝起來(lái))

          1. 做好靜態(tài)頁(yè)面,動(dòng)態(tài)效果
          2. 把前端代碼提供給后端,后端要把靜態(tài)html以及里面的假數(shù)據(jù)給刪掉,通過(guò)模板進(jìn)行動(dòng)態(tài)生成html的內(nèi)容

          [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-jL70ca3p-1658387147221)(C:Users11933Desktop前端全棧課件前后臺(tái)交互imgs服務(wù)器端渲染.png)]

          二、前后端分離,BSR

          (前后端分離,通過(guò)通用的json數(shù)據(jù)形式,不挑后端的語(yǔ)言)

          1. 做好靜態(tài)頁(yè)面,動(dòng)態(tài)效果
          2. json模擬,ajax動(dòng)態(tài)創(chuàng)建頁(yè)面
          3. 真實(shí)接口數(shù)據(jù),前后聯(lián)調(diào)

          [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-pXRCidw2-1658387147223)(C:Users11933Desktop前端全棧課件前后臺(tái)交互imgs前后端分離.png)]

          三、模板引擎

          模板引擎能夠在應(yīng)用程序中使用靜態(tài)模板文件。在運(yùn)行時(shí),模板引擎將模板文件中的變量替換為實(shí)際值,并將模板轉(zhuǎn)換為發(fā)送給客戶(hù)端的 HTML 文件。這種方法使設(shè)計(jì) HTML 頁(yè)面變得更加容易。

          Express模板引擎

          與 Express 一起使用的一些流行模板引擎是Pug、 Mustache和EJS。Express 應(yīng)用程序生成器默認(rèn)使用Pug,但它也支持其他幾個(gè)。

          需要在應(yīng)用中進(jìn)行如下設(shè)置才能讓Express渲染模板引擎:

          • views,放模板文件的目錄。例如:app.set('views', './views')。
          • view engine,要使用的模板引擎。例如,要使用 Pug 模板引擎:app.set('view engine', 'pug').
          在路由中渲染模板

          在路由渲染模板并將渲染后的 HTML 字符串發(fā)送到客戶(hù)端。

          res.render(view [, locals] [, callback])
          • view:一個(gè)字符串,view是要渲染的模板文件的文件路徑。
          • locals:一個(gè)對(duì)象,其屬性定義視圖的局部變量。
          app.get('/', function (req, res) {   res.render('index', { title: 'Hey', message: 'Hello there!' }) })
          四、ejs模板引擎的使用
          安裝ejs
          npm install ejs
          在express配置ejs模板引擎
          使用ejs模板引擎

          在app.js中添加如下代碼,配置Express使用ejs模板引擎。

          app.set('views',path.join(__dirname,'views')); //設(shè)置模板存儲(chǔ)位置app.set('view engine','ejs');

          注意:此時(shí)指定的模板目錄為views,且模板文件的后綴名為.ejs。

          設(shè)置模板后綴為html

          在app.js中添加如下代碼,配置Express使用ejs模板引擎。并指定模板后綴名為html。

          app.set('views',path.join(__dirname,'views')); //設(shè)置模板存儲(chǔ)位置app.set('view engine','html');app.engine('html',require('ejs').renderFile); //使用ejs模板引擎解析html

          注意:此時(shí)指定的模板目錄為views,且模板文件的后綴名為.html。

          ejs模板語(yǔ)法
          <%= %>   輸出標(biāo)簽 <%- %>   輸出html標(biāo)簽(html會(huì)被瀏覽器解析) <%# %>   注釋標(biāo)簽 <% %>    流程控制標(biāo)簽(寫(xiě)的是if,else,for) <%- include("user/show",{user:user})%>  導(dǎo)入公共的模板內(nèi)容

          MVC框架:

          是一種設(shè)計(jì)模式,是軟件架構(gòu)得模式,是在web開(kāi)發(fā)過(guò)程中總結(jié)的一些套路或者是模塊化的內(nèi)容。M是指業(yè)務(wù)模型(module),V是指用戶(hù)界面(view),C則是控制器(controller)。使用mvc最大的優(yōu)勢(shì)就是分層,目的是將M和V的實(shí)現(xiàn)代碼分離,存在的目的則是確保M和V的同步,一旦M改變,V應(yīng)該同步更新。MVC是相互獨(dú)立的,M,C(后端); V(前端)。路由規(guī)劃為Controller。

          JSON:

          一、概念:

          JSON(JavaScript Object Notation, JS對(duì)象表示法)簡(jiǎn)單來(lái)講,JSON 就是 Javascript 對(duì)象和數(shù)組的字符串表示法,因此,JSON 的本質(zhì)是字符串。

          作用:JSON 是一種輕量級(jí)的文本數(shù)據(jù)交換格式,在作用上類(lèi)似于 XML,專(zhuān)門(mén)用于存儲(chǔ)和傳輸數(shù)據(jù),但是 JSON 比 XML 更小、更快、更易解析。

          現(xiàn)狀:JSON 是在 2001 年開(kāi)始被推廣和使用的數(shù)據(jù)格式,到現(xiàn)今為止,JSON 已經(jīng)成為了主流的數(shù)據(jù)交換格式。

          二、JSON的兩種結(jié)構(gòu)

          JSON 就是用字符串來(lái)表示 Javascript 的對(duì)象和數(shù)組。所以,JSON 中包含對(duì)象和數(shù)組兩種結(jié)構(gòu),通過(guò)這兩種結(jié)構(gòu)的相互嵌套,可以表示各種復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。

          • 對(duì)象結(jié)構(gòu):對(duì)象結(jié)構(gòu)在 JSON 中表示為 { } 括起來(lái)的內(nèi)容。數(shù)據(jù)結(jié)構(gòu)為 { key: value, key: value, … } 的鍵值對(duì)結(jié)構(gòu)。其中,key 必須是使用英文的雙引號(hào)包裹的字符串,value 的數(shù)據(jù)類(lèi)型可以是數(shù)字、字符串、布爾值、null、數(shù)組、對(duì)象6種類(lèi)型。

            {     "name": "zs",     "age": 20,     "gender": "男",     "hobby": ["吃飯", "睡覺(jué)"]}
          • 數(shù)組結(jié)構(gòu):數(shù)組結(jié)構(gòu)在 JSON 中表示為 [ ] 括起來(lái)的內(nèi)容。數(shù)據(jù)結(jié)構(gòu)為 [ “java”, “javascript”, 30, true … ] 。數(shù)組中數(shù)據(jù)的類(lèi)型可以是數(shù)字、字符串、布爾值、null、數(shù)組、對(duì)象6種類(lèi)型。

            [ 100, 200, 300 ][ true, false, null ][ { "name": "zs", "age": 20}, { "name": "ls", "age": 30} ][ [ "aaa", "bbb", "ccc" ], [ 1, 2, 3 ] ]

          三、JSON語(yǔ)法的注意事項(xiàng)

          • 屬性名必須使用雙引號(hào)包裹
          • 字符串類(lèi)型的值必須使用雙引號(hào)包裹
          • JSON 中不允許使用單引號(hào)表示字符串
          • JSON 中不能寫(xiě)注釋
          • JSON 的最外層必須是對(duì)象或數(shù)組格式
          • 不能使用 undefined 或函數(shù)作為 JSON 的值
          • JSON 的作用:在計(jì)算機(jī)與網(wǎng)絡(luò)之間存儲(chǔ)和傳輸數(shù)據(jù)
          • JSON 的本質(zhì):用字符串來(lái)表示 Javascript 對(duì)象數(shù)據(jù)或數(shù)組數(shù)據(jù)

          四、JSON和JS對(duì)象的關(guān)系

          JSON 是 JS 對(duì)象的字符串表示法,它使用文本表示一個(gè) JS 對(duì)象的信息,本質(zhì)是一個(gè)字符串。

          //這是一個(gè)對(duì)象var obj = {a: 'Hello', b: 'World'}//這是一個(gè) JSON 字符串,本質(zhì)是一個(gè)字符串var json = '{"a": "Hello", "b": "World"}'

          五、JSON和JS對(duì)象的互轉(zhuǎn)

          • 要實(shí)現(xiàn)從 JSON 字符串轉(zhuǎn)換為 JS 對(duì)象,使用 JSON.parse() 方法
          • 要實(shí)現(xiàn)從 JS 對(duì)象轉(zhuǎn)換為 JSON 字符串,使用 JSON.stringify() 方法

          HTTP

          一、概念

          HTTP 協(xié)議即超文本傳送協(xié)議 (HyperText Transfer Protocol) ,它規(guī)定了客戶(hù)端與服務(wù)器之間進(jìn)行網(wǎng)頁(yè)內(nèi)容傳輸時(shí),所必須遵守的傳輸格式。(是一種約定與規(guī)則)

          二、請(qǐng)求(請(qǐng)求報(bào)文)

          客戶(hù)端發(fā)起的請(qǐng)求叫做 HTTP 請(qǐng)求,客戶(hù)端發(fā)送到服務(wù)器的消息,叫做 HTTP 請(qǐng)求消息,又叫做 HTTP 請(qǐng)求報(bào)文。

          請(qǐng)求消息的組成

          HTTP 請(qǐng)求消息由請(qǐng)求行(request line)、請(qǐng)求頭部( header ) 、空行 和 請(qǐng)求體 4 個(gè)部分組成。

          [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-G502I2rT-1658387147224)(C:Users11933Desktop前端全棧課件前后臺(tái)交互imgs請(qǐng)求消息組成部分.png)]

          • 請(qǐng)求行:由請(qǐng)求方式(get,post)、URL (/login?)和 HTTP 協(xié)議版本 3 個(gè)部分組成,他們之間使用空格隔開(kāi)。
          • 請(qǐng)求頭部:用來(lái)描述客戶(hù)端的基本信息,從而把客戶(hù)端相關(guān)的信息告知服務(wù)器。請(qǐng)求頭部由多行 鍵/值對(duì) 組成,每行的鍵和值之間用英文的冒號(hào)分隔。

          [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-ImfA8U4y-1658387147225)(C:Users11933Desktop前端全棧課件前后臺(tái)交互imgs請(qǐng)求頭部字段.png)]

          • 空行:最后一個(gè)請(qǐng)求頭字段的后面是一個(gè)空行,通知服務(wù)器請(qǐng)求頭部至此結(jié)束。請(qǐng)求消息中的空行,用來(lái)分隔請(qǐng)求頭部與請(qǐng)求體。
          • 請(qǐng)求體:請(qǐng)求體中存放的,是要通過(guò) POST 方式提交到服務(wù)器的數(shù)據(jù)。只有 POST 請(qǐng)求才有請(qǐng)求體,GET 請(qǐng)求沒(méi)有請(qǐng)求體!

          三、響應(yīng)(響應(yīng)報(bào)文)

          響應(yīng)消息就是服務(wù)器響應(yīng)給客戶(hù)端的消息內(nèi)容,也叫作響應(yīng)報(bào)文。

          響應(yīng)消息的組成:

          HTTP響應(yīng)消息由狀態(tài)行、響應(yīng)頭部、空行 和 響應(yīng)體 4 個(gè)部分組成。

          [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-N0rfsHa8-1658387147225)(C:Users11933Desktop前端全棧課件前后臺(tái)交互imgs響應(yīng)消息組成部分.png)]

          • 狀態(tài)行:由 HTTP 協(xié)議版本、狀態(tài)碼和狀態(tài)碼的描述文本 3 個(gè)部分組成,他們之間使用空格隔開(kāi);
          • 響應(yīng)頭部:用來(lái)描述服務(wù)器的基本信息。響應(yīng)頭部由多行 鍵/值對(duì) 組成,每行的鍵和值之間用英文的冒號(hào)分隔。
          • 空行:在最后一個(gè)響應(yīng)頭部字段結(jié)束之后,會(huì)緊跟一個(gè)空行,用來(lái)通知客戶(hù)端響應(yīng)頭部至此結(jié)束。響應(yīng)消息中的空行,用來(lái)分隔響應(yīng)頭部與響應(yīng)體。
          • 響應(yīng)體:中存放的,是服務(wù)器響應(yīng)給客戶(hù)端的資源內(nèi)容。

          四、HTTP請(qǐng)求方法

          HTTP 請(qǐng)求方法,屬于 HTTP 協(xié)議中的一部分,請(qǐng)求方法的作用是:用來(lái)表明要對(duì)服務(wù)器上的資源執(zhí)行的操作。最常用的請(qǐng)求方法是 GET 和 POST。

          [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-vwQMQrAp-1658387147226)(C:Users11933Desktop前端全棧課件前后臺(tái)交互imgshttp請(qǐng)求的方法.png)]

          五、響應(yīng)的狀態(tài)碼

          [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-28YRkP8m-1658387147227)(C:Users11933Desktop前端全棧課件前后臺(tái)交互imgshttp響應(yīng)狀態(tài)碼.png)]

          Ajax:

          一、概念

          AJAX 全稱(chēng)為(Asynchronous JavaScript And XML),是異步的JavaScript和XML。通過(guò) ajax可以在瀏覽器向服務(wù)器發(fā)送異步請(qǐng)求。最大的優(yōu)勢(shì),無(wú)刷新獲取數(shù)據(jù) 。也就是說(shuō)AJAX可以在不重新加載整個(gè)頁(yè)面的情況下,與服務(wù)器交換數(shù)據(jù)。這種異步交互的方式,使用戶(hù)單擊后,不必刷新頁(yè)面也能獲取新數(shù)據(jù)。使用Ajax,用戶(hù)可以創(chuàng)建接近本地桌面應(yīng)用的直接、高可用、更豐富、更動(dòng)態(tài)的Web用戶(hù)界面。

          二、XML

          • XML 指可擴(kuò)展標(biāo)記語(yǔ)?,HTML 超文本標(biāo)記語(yǔ)言
          • XML被設(shè)計(jì)用來(lái)傳輸和存儲(chǔ)數(shù)據(jù)
          • XML和HTML類(lèi)似,不同的是HTML都是預(yù)定義的標(biāo)簽,而XML沒(méi)有預(yù)定義標(biāo)簽,全部都是自定義的標(biāo)簽,用來(lái)表示一些數(shù)據(jù)。

          最開(kāi)始是前后臺(tái)進(jìn)行數(shù)據(jù)交互的語(yǔ)言,現(xiàn)在是JSON。

          '{"title":"三體","author":"zs","price":30}'<book>     <title>三體</title>     <author>劉慈欣</author>     <price>30.00</price></book>

          三、特點(diǎn)

          優(yōu)點(diǎn):

          1. 可以無(wú)需刷新頁(yè)面與服務(wù)器進(jìn)行通信
          2. 允許你根據(jù)用戶(hù)事件來(lái)更新部分頁(yè)面內(nèi)容

          缺點(diǎn):

          1. 沒(méi)有瀏覽歷史不能回退
          2. 存在跨越問(wèn)題 同源策略:協(xié)議,域名,端口號(hào)
          3. SEO不友好

          四、發(fā)送請(qǐng)求

          • get方式,以及請(qǐng)求參數(shù)
          // 1.創(chuàng)建對(duì)象var xhr=new XMLHttpRequest();// 2.初始化,設(shè)置請(qǐng)求方法和urlxhr.open("GET","http://127.0.0.1:3000/server?username=zs&password=1234");// 3.發(fā)送xhr.send();// 4.綁定事件,處理服務(wù)端返回得結(jié)果// readstate  xhr得屬性  狀態(tài)  0,1,2,3,4xhr.onreadystatechange=function(){     // 服務(wù)器返回得結(jié)果     if(xhr.readyState==4){         // 判斷響應(yīng)得狀態(tài)碼         if(xhr.status==200){             // 行,頭,體             console.log(xhr.status);             console.log(xhr.statusText);             console.log(xhr.response);             console.log(xhr.getAllResponseHeaders());         }     }}

          項(xiàng)目:

          一、對(duì)密碼進(jìn)行加密處理

          JavaScript使用CryptoJS加解密。CryptoJS時(shí)一個(gè)JavaScript的加解密的工具包。它支持多種的算法:MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,進(jìn)行 AES、DES、Rabbit、RC4、Triple DES 加解密。在項(xiàng)目中如果要對(duì)前后端傳輸?shù)臄?shù)據(jù)雙向加密, 比如避免使用明文傳輸用戶(hù)名,密碼等數(shù)據(jù)。 就需要對(duì)前后端數(shù)據(jù)用同種方法進(jìn)行加密,方便解密。

          使用步驟:

          • 運(yùn)行如下命令,安裝 CryptoJS
          npm i crypto-js
          • /login.js 中,導(dǎo)入 crypto-js
          const crypto = require('crypto-js')
          • ASE進(jìn)行純文本加密:
          //加密var a=crypto.AES.encrypt("abc","key").toString();    //SecrectKey 秘鑰//解密var b=crypto.AES.decrypt(a,"key").toString(crypto.enc.Utf8);  //按照UTF8編碼解析出原始字符串

          二、表單校驗(yàn)規(guī)則

          在實(shí)際開(kāi)發(fā)中,前后端都需要對(duì)表單的數(shù)據(jù)進(jìn)行合法性的驗(yàn)證,而且,后端做為數(shù)據(jù)合法性驗(yàn)證的最后一個(gè)關(guān)口,在攔截非法數(shù)據(jù)方面,起到了至關(guān)重要的作用。使用第三方數(shù)據(jù)驗(yàn)證模塊,來(lái)降低出錯(cuò)率、提高驗(yàn)證的效率與可維護(hù)性。

          步驟:

          • 安裝 joi 包,為表單中攜帶的每個(gè)數(shù)據(jù)項(xiàng),定義驗(yàn)證規(guī)則:
          npm install joi
          • 安裝 @escook/express-joi 中間件,來(lái)實(shí)現(xiàn)自動(dòng)對(duì)表單數(shù)據(jù)進(jìn)行驗(yàn)證的功能:
          npm i @escook/express-joi
          • 新建 /schema/login.js 用戶(hù)信息驗(yàn)證規(guī)則模塊:
          const joi = require('joi')/**  * string() 值必須是字符串  * alphanum() 值只能是包含 a-zA-Z0-9 的字符串  * min(length) 最小長(zhǎng)度  * max(length) 最大長(zhǎng)度  * required() 值是必填項(xiàng),不能為 undefined  * pattern(正則表達(dá)式) 值必須符合正則表達(dá)式的規(guī)則  */// 用戶(hù)名的驗(yàn)證規(guī)則const username = joi.string().required();// 密碼的驗(yàn)證規(guī)則const password = joi.string().pattern(/^[S]{6,12}$/).required();// 登錄表單的驗(yàn)證規(guī)則對(duì)象exports.login_schema = {   // 表示需要對(duì) req.body 中的數(shù)據(jù)進(jìn)行驗(yàn)證   body: {     username,     password,   },}
          • 修改 /router/admin/login.js 中的代碼:
          // 1. 導(dǎo)入驗(yàn)證表單數(shù)據(jù)的中間件const expressJoi = require('@escook/express-joi')// 2. 導(dǎo)入需要的驗(yàn)證規(guī)則對(duì)象const { login_schema } = require('../../schema/login');// 3登錄功能router.post("/",expressJoi(login_schema),(req,res)=>{}];
          • index.js 的全局錯(cuò)誤級(jí)別中間件中,捕獲驗(yàn)證失敗的錯(cuò)誤,并把驗(yàn)證失敗的結(jié)果響應(yīng)給客戶(hù)端:
          const joi = require('joi')// 錯(cuò)誤中間件app.use(function (err, req, res, next) {   // 數(shù)據(jù)驗(yàn)證失敗   if (err instanceof joi.ValidationError) return res.send(err);   // 未知錯(cuò)誤   res.send(err)})

          三、四種常見(jiàn)的POST提交數(shù)據(jù)方式

          HTTP協(xié)議是以ASCII碼傳輸,建立在TCP/IP協(xié)議之上的應(yīng)用層規(guī)范。規(guī)范把 HTTP 請(qǐng)求分為三個(gè)部分:狀態(tài)行、請(qǐng)求頭、消息主體。協(xié)議規(guī)定 POST 提交的數(shù)據(jù)必須放在消息主體(entity-body)中,但協(xié)議并沒(méi)有規(guī)定數(shù)據(jù)必須使用什么編碼方式Content-Type。

          服務(wù)端根據(jù)請(qǐng)求頭(headers)中的Content-Type字段來(lái)獲知請(qǐng)求中的消息主體是用何種方式編碼,再對(duì)主體進(jìn)行解析。所以說(shuō)到POST提交數(shù)據(jù)方案,包含了Content-Type 和消息主體編碼方式兩部分。Content-Type的四種值分別代表四種方式,具體如下:

          • 方式一:application/x-www-form-urlencoded

          瀏覽器的原生form表單,如果不設(shè)置enctype屬性,那么最終就會(huì)以 application/x-www-form-urlencoded方式提交數(shù)據(jù)。Content-Type被指定為application/x-www-form-urlencoded提交的數(shù)據(jù)按照key=val&key=val的方式進(jìn)行編碼,并且key和val都進(jìn)行了URL轉(zhuǎn)碼。服務(wù)端例如 PHP 中,使用$_POST[′key′]可以獲取到值。

          • 方式二:multipart/form-data

          常見(jiàn)的POST數(shù)據(jù)提交的方式。這種方式支持文件上傳,不過(guò)必須要設(shè)置form的enctyped等于這個(gè)值。使用multipart/form-data方式會(huì)生成了一個(gè)boundary 來(lái)分割不同的字段,為了避免與正文重復(fù),boundary是一段很長(zhǎng)的隨機(jī)拼接的字符串。然后Content-Type指明數(shù)據(jù)是以mutipart/form-data來(lái)編碼并包括進(jìn)本次請(qǐng)求的boundary 值。消息主體最后以 –boundary–標(biāo)示結(jié)束。

          • 方式三:application/json

          由于JSON規(guī)范的流行,現(xiàn)在越來(lái)越多的開(kāi)發(fā)者將application/json這個(gè)Content-Type作為響應(yīng)頭。用來(lái)告訴服務(wù)端消息主體是序列化后的JSON字符串。除了低版本IE之外各大瀏覽器都原生支持 JSON.stringify,服務(wù)端語(yǔ)言也都有處理JSON的函數(shù),JSON能格式支持比鍵值對(duì)復(fù)雜得多的結(jié)構(gòu)化數(shù)據(jù),普通鍵值對(duì)中的值只能是字符串,而使用json,鍵值對(duì)可以重復(fù)嵌套。

          • 方式四:text/xml

          它是一種使用HTTP作為傳輸協(xié)議,XML作為編碼方式的遠(yuǎn)程調(diào)用規(guī)范。不過(guò)后來(lái)使用很少。也許在十多年前,在json還未出來(lái)之前數(shù)據(jù)交互對(duì)接。

          總之a(chǎn)pplication/x-www-form-urlencoded和multipart/form-data兩種POST方式都是瀏覽器原生支持的,是普遍使用的兩種方式,application/json是現(xiàn)在比較流行的新趨勢(shì)。

          四、multer

          • 安裝multer
          npm i multer
          • 導(dǎo)入multer
          const multer  = require('multer')
          • 配置multer接收到的文件存儲(chǔ)的文件夾和,存放的圖片的名字
          //上傳文件存放路徑、及文件命名const storage = multer.diskStorage({     destination: path.join(__dirname ,'../static/uploads'),  //確定上傳文件的物理位置     filename: function (req, file, cb) { //自定義設(shè)置文件的名字,根據(jù)上傳時(shí)間的時(shí)間戳來(lái)命名         let type = file.originalname.split('.')[1]         cb(null, `${file.fieldname}-${Date.now().toString(16)}.${type}`)     }})

          1.sotrage是一個(gè)配置對(duì)象。他是通過(guò)multer.diskstorage存儲(chǔ)引擎生成的。multer.diskstorage需要傳遞一個(gè)配置對(duì)象,這里的配置對(duì)象里面接收兩個(gè)參數(shù)。第一個(gè)參數(shù)為destination,它的值為一個(gè)路徑字符串,代表的含義是當(dāng)multer處理完成前端傳遞過(guò)來(lái)的文件之后要把這個(gè)文件存儲(chǔ)在哪里。這個(gè)文件夾無(wú)需手動(dòng)創(chuàng)建,在接受文件的時(shí)候會(huì)自動(dòng)創(chuàng)建。這里建議使用path模塊進(jìn)行拼接,不容易出錯(cuò)。第二個(gè)參數(shù)為一個(gè)回調(diào)函數(shù),這里形參要用三個(gè)進(jìn)行占位。multer中間件在解析前端提交的文件的時(shí)候會(huì)調(diào)用這個(gè)方法,調(diào)用的時(shí)候會(huì)給這個(gè)filename指向的函數(shù)傳遞三個(gè)參數(shù),第二個(gè)值為前端傳遞過(guò)來(lái)文件信息,第三個(gè)參數(shù)cb為一個(gè)函數(shù),cb函數(shù)調(diào)用的第二個(gè)參數(shù)指定的就是當(dāng)前解析完成后的保存到destination指向的目錄的文件名。

          • 應(yīng)用這個(gè)配置到multer實(shí)例里面
          const upload = multer({storage});
          • 在需要接收文件的路由里面應(yīng)用upload.single(‘file’)中間件
          (1).這個(gè)file是前端提交表單過(guò)來(lái)的時(shí)候表單的字段名稱(chēng)。(2).upload是用multer這個(gè)庫(kù)里的頂級(jí)構(gòu)造函數(shù)生成的實(shí)例。
          • 總體思路梳理:

          實(shí)際網(wǎng)頁(yè)開(kāi)發(fā)當(dāng)中,我們前端需要向后端提交一些像mp4,mp3,圖片系列的東西,需要在后端進(jìn)行接收。那么這里就可以使用Multer中間件來(lái)接收文件,對(duì)前端傳遞過(guò)來(lái)的文件做一些處理。

          1. multer是啥? Multer是Express官方推出的,用于node.js 處理前端以multipart/form-data請(qǐng)求數(shù)據(jù)處理的一個(gè)中間件。注意: Multer 不會(huì)處理任何非 multipart/form-data 類(lèi)型的表單數(shù)據(jù)

          2. 原理: Multer實(shí)例的single(‘###’) 是一個(gè)方法,這個(gè)方法被當(dāng)作中間件放在某一個(gè)路由上時(shí)。就會(huì)給express 的 request 對(duì)象中添加一個(gè) body 對(duì)象 以及 file 或 files 對(duì)象 。 body 對(duì)象包含表單的文本域信息,file 或 files 對(duì)象包含對(duì)象表單上傳的文件信息。下圖就是req.file的模樣。當(dāng)前端請(qǐng)求后臺(tái)接口。匹配當(dāng)前路由的時(shí)候,先經(jīng)過(guò)這個(gè)multer中間件,這個(gè)中間件就會(huì)解析前端傳過(guò)來(lái)的文件,會(huì)把文件保存在上面第三步配置文件解析完成后的文件夾內(nèi),名字也會(huì)重命名成上面第三步配置文件解析完成的文件名。同時(shí),會(huì)在req的身上掛載一個(gè)file對(duì)象。這個(gè)file對(duì)象就是當(dāng)前上傳文件的信息。我們可以通過(guò)req.file.filename拿到這個(gè)重命名后的文件名,然后把這個(gè)文件名保存到數(shù)據(jù)庫(kù)里面。前端如果想訪問(wèn)之前上傳的圖片,后臺(tái)只需要把數(shù)據(jù)庫(kù)里的文件名取到,隨后映射成我們請(qǐng)求的路徑,去請(qǐng)求public靜態(tài)資源下的存放這些文件的文件夾就可以了。

          3. multer是一個(gè)中間件,我建議把這個(gè)中間件寫(xiě)成一個(gè)單獨(dú)的文件,最后把配置好的multer實(shí)例暴露出去,在需要他的路由里面當(dāng)作中間件去應(yīng)用它。就可以很快捷的處理前端發(fā)送過(guò)來(lái)的文件。而無(wú)需每個(gè)文件都寫(xiě)一遍。也更加符合我們模塊化編程的思想。下圖是我multer文件的配置。

          五、富文本編輯器

          富文本編輯器,Multi-function Text Editor, 簡(jiǎn)稱(chēng) MTE, 是一種可內(nèi)嵌于瀏覽器,所見(jiàn)即所得的文本編輯器。它提供類(lèi)似于 Microsoft Word 的編輯功能,容易被不會(huì)編寫(xiě) HTML 的用戶(hù)并需要設(shè)置各種文本格式的用戶(hù)所喜愛(ài)。

          富文本編輯器不同于文本編輯器,程序員可到網(wǎng)上下載免費(fèi)的富文本編輯器內(nèi)嵌于自己的網(wǎng)站或程序里(當(dāng)然付費(fèi)的功能會(huì)更強(qiáng)大些),方便用戶(hù)編輯文章或信息。

          [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-9D1VzMYl-1658387147228)(C:Users11933Desktop前端全棧課件前后臺(tái)交互imgs富文本編輯器.png)]

          layui 富文本編輯器(layedit):

          • 使用:

            <textarea id="demo" style="display: none;"></textarea>layui.use(['layedit'],function(){     layedit.build("demo")})
          • layedit基礎(chǔ)的方法:

            方法名 描述
            var index = layedit.build(id, options) 用于建立編輯器的核心方法index:即該方法返回的索引參數(shù) id: 實(shí)例元素(一般為textarea)的id值參數(shù) options:編輯器的可配置項(xiàng),下文會(huì)做進(jìn)一步介紹
            layedit.set(options) 設(shè)置編輯器的全局屬性即上述build方法的options
            layedit.getContent(index) 獲得編輯器的內(nèi)容參數(shù) index: 即執(zhí)行l(wèi)ayedit.build返回的值
            layedit.getText(index) 獲得編輯器的純文本內(nèi)容參數(shù) index: 同上
            layedit.sync(index) 用于同步編輯器內(nèi)容到textarea(一般用于異步提交)參數(shù) index: 同上
            layedit.getSelection(index) 獲取編輯器選中的文本參數(shù) index: 同上
          • 編輯器屬性設(shè)置:

            屬性 類(lèi)型 描述
            tool Array 重新定制編輯器工具欄,如: tool: [‘link’, ‘unlink’, ‘face’]
            hideTool Array 不顯示編輯器工具欄,一般用于隱藏默認(rèn)配置的工具bar
            height Number 設(shè)定編輯器的初始高度
            uploadImage Object 設(shè)定圖片上傳接口,如:uploadImage: {url: ‘/upload/’, type: ‘post’}
          • 富文本編輯器工具欄:

             let richtextInex =  layedit.build('richtext', {      tool: [          'strong' //加粗          , 'italic' //斜體          , 'underline' //下劃線          , 'del' //刪除線           , '|' //分割線           , 'left' //左對(duì)齊          , 'center' //居中對(duì)齊          , 'right' //右對(duì)齊          , 'image' //插入圖片      ],      uploadImage:{url:'/uploadrichtext',type:'POST'}  })

          六、express-session

          (一)、Session簡(jiǎn)單介紹
          session 是另一種記錄客戶(hù)狀態(tài)的機(jī)制,不同的是 Cookie 保存在客戶(hù)端瀏覽器中,而 session 保存在服務(wù)器上。Session的用途:
          session運(yùn)行在服務(wù)器端,當(dāng)客戶(hù)端第一次訪問(wèn)服務(wù)器時(shí),可以將客戶(hù)的登錄信息保存。
          當(dāng)客戶(hù)訪問(wèn)其他頁(yè)面時(shí),可以判斷客戶(hù)的登錄狀態(tài),做出提示,相當(dāng)于登錄攔截。
          session可以和Redis或者數(shù)據(jù)庫(kù)等結(jié)合做持久化操作,當(dāng)服務(wù)器掛掉時(shí)也不會(huì)導(dǎo)致某些客戶(hù)信息(購(gòu)物車(chē))
          丟失。

          (二)、Session的工作流程
          當(dāng)瀏覽器訪問(wèn)服務(wù)器并發(fā)送第一次請(qǐng)求時(shí),服務(wù)器端會(huì)創(chuàng)建一個(gè)session對(duì)象,生成一個(gè)類(lèi)似于
          key,value的鍵值對(duì),然后將key(cookie)返回到瀏覽器(客戶(hù))端,瀏覽器下次再訪問(wèn)時(shí),攜帶key(cookie),
          找到對(duì)應(yīng)的session(value)。 客戶(hù)的信息都保存在session中。

          (三)、Cookie和Session區(qū)別:

          • cookie 數(shù)據(jù)存放在客戶(hù)的瀏覽器上,session 數(shù)據(jù)放在服務(wù)器上。

          • cookie 不是很安全,別人可以分析存放在本地的 COOKIE 并進(jìn)行 COOKIE 欺騙 考慮到安全應(yīng)當(dāng)使用 session。

          • session 會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問(wèn)增多,會(huì)比較占用你服務(wù)器的性能 考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用 COOKIE。

          • 單個(gè) cookie 保存的數(shù)據(jù)不能超過(guò) 4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存 20 個(gè) cookie。

          (四)、express-session的使用

          • 安裝 express-session:

            npm install express-session
          • 引入express-session:

            var session = require("express-session");
          • 設(shè)置官方文檔提供的中間件:

            app.use(session({     secret: 'keyboard cat',     resave: true,     saveUninitialized: true }))
          • 使用:

            設(shè)置值 req.session.username = "張三"; 獲取值 req.session.username
          • express-session的常用參數(shù):

          1. name - cookie的名字(原屬性名為 key)。(默認(rèn):’connect.sid’)2. store - session存儲(chǔ)實(shí)例3. secret - 用它來(lái)對(duì)session cookie簽名,防止篡改4. cookie - session cookie設(shè)置 (默認(rèn):{ path: ‘/‘, httpOnly: true,secure: false, maxAge: null })5. genid - 生成新session ID的函數(shù) (默認(rèn)使用uid2庫(kù))6. rolling - 在每次請(qǐng)求時(shí)強(qiáng)行設(shè)置cookie,這將重置cookie過(guò)期時(shí)間(默認(rèn):false)7. resave - 強(qiáng)制保存session即使它并沒(méi)有變化 (默認(rèn): true)8. proxy - 當(dāng)設(shè)置了secure cookies(通過(guò)”x-forwarded-proto” header )時(shí)信任反向代理。當(dāng)設(shè)定為true時(shí), ”x-forwarded-proto” header 將被使用。當(dāng)設(shè)定為false時(shí),所有headers將被忽略。當(dāng)該屬性沒(méi)有被設(shè)定時(shí),將使用Express的trust proxy。9. saveUninitialized - 強(qiáng)制將未初始化的session存儲(chǔ)。當(dāng)新建了一個(gè)session且未設(shè)定屬性或值時(shí),它就處于 未初始化狀態(tài)。在設(shè)定一個(gè)cookie前,這對(duì)于登陸驗(yàn)證,減輕服務(wù)端存儲(chǔ)壓力,權(quán)限控制是有幫助的。(默認(rèn):true)10. unset - 控制req.session是否取消(例如通過(guò) delete,或者將它的值設(shè)置為null)。這可以使session保持
          • express-session的常用方法:
          1. Session.destroy():刪除session,當(dāng)檢測(cè)到客戶(hù)端關(guān)閉時(shí)調(diào)用。2. Session.reload():當(dāng)session有修改時(shí),刷新session。3. Session.regenerate():將已有session初始化。4. Session.save():保存session。
          • 使用案例:
          //配置中間件app.use(session({     secret: 'this is string key',   // 可以隨便寫(xiě)。一個(gè) String 類(lèi)型的字符串,作為服務(wù)器端生成 session 的簽名     name:'session_id',/*保存在本地cookie的一個(gè)名字 默認(rèn)connect.sid  可以不設(shè)置*/     resave: false,   /*強(qiáng)制保存 session 即使它并沒(méi)有變化,。默認(rèn)為 true。建議設(shè)置成 false。*/     saveUninitialized: true,   //強(qiáng)制將未初始化的 session 存儲(chǔ)。  默認(rèn)值是true  建議設(shè)置成true     cookie: {         maxAge:5000    /*過(guò)期時(shí)間*/      },   /*secure https這樣的情況才可以訪問(wèn)cookie*/      //設(shè)置過(guò)期時(shí)間比如是30分鐘,只要游覽頁(yè)面,30分鐘沒(méi)有操作的話在過(guò)期          rolling:true //在每次請(qǐng)求時(shí)強(qiáng)行設(shè)置 cookie,這將重置 cookie 過(guò)期時(shí)間(默認(rèn):false)}))

          七、表單事件

          • Form 對(duì)象屬性:
          屬性 描述
          action 接收請(qǐng)求的URL
          elements 表單中的所有控件元素集合
          length 表單控件的個(gè)數(shù)
          enctype 編碼類(lèi)型 例:enctype=“multipart/form-data”
          name 表單元素名稱(chēng)
          • Form 對(duì)象方法:
          方法 描述
          reset() 把表單的所有輸入元素重置為它們的默認(rèn)值。
          submit() 提交表單。
          • Form 對(duì)象事件:
          事件 描述
          onreset 在重置表單元素之前調(diào)用。
          onsubmit 在提交表單之前調(diào)用。
          • 表單控件的屬性:
          屬性 描述
          value 獲取和設(shè)置值
          disabled 獲取或設(shè)置表單控件是否禁用值為true或 false
          type 讀取表單控件的類(lèi)型
          form 所在表單元素對(duì)象
          readOnly 控件只讀屬性 Boolean 不能更改只能復(fù)制和讀取
          name 獲取與設(shè)置name字段名
          • 表單控件的事件:
          事件 描述
          onblur 當(dāng)失去焦點(diǎn)的時(shí)候
          onfocus 當(dāng)獲取焦點(diǎn)的時(shí)候
          onchange 當(dāng)內(nèi)容改變并失去焦點(diǎn)的時(shí)候
          oninput 在用戶(hù)輸入時(shí)觸發(fā)
          • 表單控件的方法:
          方法 描述
          focus() 獲得焦點(diǎn)
          blur() 失去焦點(diǎn)
          select() 選擇文本控件中的所有文本內(nèi)容

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)