站長資訊網
        最全最豐富的資訊網站

        總結Node.js模塊開發及常用技巧分享

        一、模塊化

        模塊化做為一種現代化的設計方法,這個概念最早起源于生產制造行業。如今這個概念已經被各行各業來衍生應用,在軟件開發中也大量的采用了模塊化思想。

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

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

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

        為什么需要模塊化:

        • 程序復雜度上升代碼越寫越多,在一個文件里代碼就會越來越長,不易維護。(把完成特定功能的代碼分組,分別放到不同的文件里,這樣,每個文件包含的代碼就相對較少)

        • JavaScript 有復雜的依賴關系的時候就很容易出現一些變量的屬性或方法被覆蓋或改寫,導致變量污染。這是因為js沒有命名空間,不像其他語言通過命名空間可以有效的避免重名問題。

        • 想要存在JavaScript 私有的變量

        模塊化思想解決問題:

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

        • 命名沖突:為了避免在JavaScript中的全局污染,我們通過模塊化的方式利用函數作用域來構建命名空間,避免命名沖突。

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

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

        (二)、什么是Nodejs模塊

        為了讓Nodejs的文件可以相互調用,Nodejs基于CommonJS規范提供了一個簡單的模塊系統。(nodejs實現并遵守CommonJS規范的)。

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

        //exports語法示例  // 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語法示例  //sum.js function sum(a,b){     return a+b; } module.exports= sum; //main.js var sum = require('./sum'); sum(10,20);// 30

        CommonJS 規定:

        • 每個模塊內部,module 變量代表當前模塊

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

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

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

        Node.js 中根據模塊來源的不同,將模塊分為了 3 大類,分別是:

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

        • 自定義模塊(用戶創建的每個 .js 文件,都是自定義模塊)

        • 第三方模塊(包)(由第三方開發出來的模塊,并非官方提供的內置模塊,也不是用戶創建的自定義模塊,使用前需要先下載)

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

        (四)、模塊作用域

        • 和函數作用域類似,在自定義模塊中定義的變量、方法等成員,只能在當前模塊內被訪問,這種模塊級別的訪問限制,叫做模塊作用域。
        • 模塊作用域的好處:防止了全局變量污染的問題

        二、npm與包

        (一)、包的介紹

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

        (二)、npm的使用

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

        (三)、全局安裝nrm nodemon

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

        手動切換方法:

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

        安裝 nrm:

        $ npm i nrm -g

        查看nrm 內置的幾個 npm 源的地址:

        $ nrm ls

        結果如下:

          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

        查看當前的鏡像源:

        npm config get register

        (四)、淘寶cnpm工具

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

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

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

        安裝包

        cnpm install [模塊名]

        三、路由

        路由:根據不同的路徑返回不同的頁面。

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

        獲取請求參數:login頁面發get,post請求,到/api/login

        靜態資源托管:

        express

        Express是一個基于 Node.js 平臺,快速、開放、極簡的 Web 開發框架。

        一、下載與安裝

        $ npm install express --save

        案例:第一個express案例。

        二、路由

        所謂的路由就是客戶端用來與后端服務器進行交互的一種方式,客戶端采用特定的URL與請求方法來訪問服務器端,服務器端通過響應返回特定資源。

        路由的定義由如下結構組成:

        app.METHOD(PATH, HANDLER)
        名稱 描述
        app app 是一個 express 實例
        METHOD METHOD用于指定要匹配的HTTP請求方式
        PATH PATH是服務器端的路徑
        HANDLER 是當路由匹配時需要執行的處理程序(回調函數)

        路由路徑和請求方法一起定義了請求的端點,它可以是字符串,字符串模式以及正則表達式。

        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可以一次或者多次的重復})app.get('/ab*cd', function (req, res) {   res.send('ab*cd')  //在ab,cd之間隨意寫入任意字符})app.get('/ab(cd)?e', function (req, res) {   res.send('ab(cd)?e')})

        可以為請求處理提供多個回調函數,其行為類似中間件。

        案例:中間件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.應用級中間件

        在Express程序中,使用 app.use()app.METHOD() 方法將中間件綁定到應用程序對象(app)。

        凡是掛載在app身上的都是應用級中間件。

        app.use() : 應用中的每個請求都可以執行其代碼

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

        2.路由級中間件

        路由器級中間件的工作方式與應用級中間件相同,只是它綁定到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.錯誤處理中間件

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

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

        4.內置中間件

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

        • express.json使用 JSON 有效負載解析傳入請求。注意:可用于 Express 4.16.0+

          application/json

          由于JSON規范的流行,現在越來越多的開發者將application/json這個Content-Type作為響應頭。用來告訴服務端消息主體是序列化后的JSON字符串。除了低版本IE之外各大瀏覽器都原生支持 JSON.stringify,服務端語言也都有處理JSON的函數,JSON能格式支持比鍵值對復雜得多的結構化數據,普通鍵值對中的值只能是字符串,而使用json,鍵值對可以重復嵌套。

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

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

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

        5.第三方中間件

        四、獲取請求參數

        • req.query 是一個可獲取客戶端get請求 查詢字符串 轉成的對象,默認為{}。
        • req.body 包含在請求體中提交的數據鍵值對。默認情況下undefined,當使用解析中間件express.json()express.urlencoded()

        五、靜態資源托管

        為了提供諸如圖像、CSS 文件和 JavaScript 文件之類的靜態文件,請使用 Express 中的 express.static 內置中間件函數。

        語法:

        express.static內置中間件函數語法:

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

        靜態資源示例:

        例如,通過如下代碼就可以將 public 目錄下的圖片、CSS 文件、JavaScript 文件對外開放訪問了:

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

        現在,你就可以訪問 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 在靜態目錄查找文件,因此,存放靜態文件的目錄名不會出現在 URL 中。

        多個靜態資源目錄:

        如果要使用多個靜態資源目錄,請多次調用 express.static 中間件函數:

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

        訪問靜態資源文件時,express.static 中間件函數會根據目錄的添加順序查找所需的文件。

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

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

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

        現在,你就可以通過帶有 /static 前綴地址來訪問 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

        六、模板引擎

        一、.服務端渲染 SSR

        后端嵌套模板,后端渲染模板 (后端把頁面組裝起來)

        1. 做好靜態頁面,動態效果
        2. 把前端代碼提供給后端,后端要把靜態html以及里面的假數據給刪掉,通過模板進行動態生成html的內容

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

        二、前后端分離,BSR

        (前后端分離,通過通用的json數據形式,不挑后端的語言)

        1. 做好靜態頁面,動態效果
        2. json模擬,ajax動態創建頁面
        3. 真實接口數據,前后聯調

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

        三、模板引擎

        模板引擎能夠在應用程序中使用靜態模板文件。在運行時,模板引擎將模板文件中的變量替換為實際值,并將模板轉換為發送給客戶端的 HTML 文件。這種方法使設計 HTML 頁面變得更加容易。

        Express模板引擎

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

        需要在應用中進行如下設置才能讓Express渲染模板引擎:

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

        在路由渲染模板并將渲染后的 HTML 字符串發送到客戶端。

        res.render(view [, locals] [, callback])
        • view:一個字符串,view是要渲染的模板文件的文件路徑。
        • locals:一個對象,其屬性定義視圖的局部變量。
        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')); //設置模板存儲位置app.set('view engine','ejs');

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

        設置模板后綴為html

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

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

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

        ejs模板語法
        <%= %>   輸出標簽 <%- %>   輸出html標簽(html會被瀏覽器解析) <%# %>   注釋標簽 <% %>    流程控制標簽(寫的是if,else,for) <%- include("user/show",{user:user})%>  導入公共的模板內容

        MVC框架:

        是一種設計模式,是軟件架構得模式,是在web開發過程中總結的一些套路或者是模塊化的內容。M是指業務模型(module),V是指用戶界面(view),C則是控制器(controller)。使用mvc最大的優勢就是分層,目的是將M和V的實現代碼分離,存在的目的則是確保M和V的同步,一旦M改變,V應該同步更新。MVC是相互獨立的,M,C(后端); V(前端)。路由規劃為Controller。

        JSON:

        一、概念:

        JSON(JavaScript Object Notation, JS對象表示法)簡單來講,JSON 就是 Javascript 對象和數組的字符串表示法,因此,JSON 的本質是字符串。

        作用:JSON 是一種輕量級的文本數據交換格式,在作用上類似于 XML,專門用于存儲和傳輸數據,但是 JSON 比 XML 更小、更快、更易解析。

        現狀:JSON 是在 2001 年開始被推廣和使用的數據格式,到現今為止,JSON 已經成為了主流的數據交換格式。

        二、JSON的兩種結構

        JSON 就是用字符串來表示 Javascript 的對象和數組。所以,JSON 中包含對象和數組兩種結構,通過這兩種結構的相互嵌套,可以表示各種復雜的數據結構。

        • 對象結構:對象結構在 JSON 中表示為 { } 括起來的內容。數據結構為 { key: value, key: value, … } 的鍵值對結構。其中,key 必須是使用英文的雙引號包裹的字符串,value 的數據類型可以是數字、字符串、布爾值、null、數組、對象6種類型。

          {     "name": "zs",     "age": 20,     "gender": "男",     "hobby": ["吃飯", "睡覺"]}
        • 數組結構:數組結構在 JSON 中表示為 [ ] 括起來的內容。數據結構為 [ “java”, “javascript”, 30, true … ] 。數組中數據的類型可以是數字、字符串、布爾值、null、數組、對象6種類型。

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

        三、JSON語法的注意事項

        • 屬性名必須使用雙引號包裹
        • 字符串類型的值必須使用雙引號包裹
        • JSON 中不允許使用單引號表示字符串
        • JSON 中不能寫注釋
        • JSON 的最外層必須是對象或數組格式
        • 不能使用 undefined 或函數作為 JSON 的值
        • JSON 的作用:在計算機與網絡之間存儲和傳輸數據
        • JSON 的本質:用字符串來表示 Javascript 對象數據或數組數據

        四、JSON和JS對象的關系

        JSON 是 JS 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質是一個字符串。

        //這是一個對象var obj = {a: 'Hello', b: 'World'}//這是一個 JSON 字符串,本質是一個字符串var json = '{"a": "Hello", "b": "World"}'

        五、JSON和JS對象的互轉

        • 要實現從 JSON 字符串轉換為 JS 對象,使用 JSON.parse() 方法
        • 要實現從 JS 對象轉換為 JSON 字符串,使用 JSON.stringify() 方法

        HTTP

        一、概念

        HTTP 協議即超文本傳送協議 (HyperText Transfer Protocol) ,它規定了客戶端與服務器之間進行網頁內容傳輸時,所必須遵守的傳輸格式。(是一種約定與規則)

        二、請求(請求報文)

        客戶端發起的請求叫做 HTTP 請求,客戶端發送到服務器的消息,叫做 HTTP 請求消息,又叫做 HTTP 請求報文。

        請求消息的組成

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

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

        • 請求行:由請求方式(get,post)、URL (/login?)和 HTTP 協議版本 3 個部分組成,他們之間使用空格隔開。
        • 請求頭部:用來描述客戶端的基本信息,從而把客戶端相關的信息告知服務器。請求頭部由多行 鍵/值對 組成,每行的鍵和值之間用英文的冒號分隔。

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

        • 空行:最后一個請求頭字段的后面是一個空行,通知服務器請求頭部至此結束。請求消息中的空行,用來分隔請求頭部與請求體。
        • 請求體:請求體中存放的,是要通過 POST 方式提交到服務器的數據。只有 POST 請求才有請求體,GET 請求沒有請求體!

        三、響應(響應報文)

        響應消息就是服務器響應給客戶端的消息內容,也叫作響應報文。

        響應消息的組成:

        HTTP響應消息由狀態行、響應頭部、空行 和 響應體 4 個部分組成。

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

        • 狀態行:由 HTTP 協議版本、狀態碼和狀態碼的描述文本 3 個部分組成,他們之間使用空格隔開;
        • 響應頭部:用來描述服務器的基本信息。響應頭部由多行 鍵/值對 組成,每行的鍵和值之間用英文的冒號分隔。
        • 空行:在最后一個響應頭部字段結束之后,會緊跟一個空行,用來通知客戶端響應頭部至此結束。響應消息中的空行,用來分隔響應頭部與響應體。
        • 響應體:中存放的,是服務器響應給客戶端的資源內容。

        四、HTTP請求方法

        HTTP 請求方法,屬于 HTTP 協議中的一部分,請求方法的作用是:用來表明要對服務器上的資源執行的操作。最常用的請求方法是 GET 和 POST。

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

        五、響應的狀態碼

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

        Ajax:

        一、概念

        AJAX 全稱為(Asynchronous JavaScript And XML),是異步的JavaScript和XML。通過 ajax可以在瀏覽器向服務器發送異步請求。最大的優勢,無刷新獲取數據 。也就是說AJAX可以在不重新加載整個頁面的情況下,與服務器交換數據。這種異步交互的方式,使用戶單擊后,不必刷新頁面也能獲取新數據。使用Ajax,用戶可以創建接近本地桌面應用的直接、高可用、更豐富、更動態的Web用戶界面。

        二、XML

        • XML 指可擴展標記語?,HTML 超文本標記語言
        • XML被設計用來傳輸和存儲數據
        • XML和HTML類似,不同的是HTML都是預定義的標簽,而XML沒有預定義標簽,全部都是自定義的標簽,用來表示一些數據。

        最開始是前后臺進行數據交互的語言,現在是JSON。

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

        三、特點

        優點:

        1. 可以無需刷新頁面與服務器進行通信
        2. 允許你根據用戶事件來更新部分頁面內容

        缺點:

        1. 沒有瀏覽歷史不能回退
        2. 存在跨越問題 同源策略:協議,域名,端口號
        3. SEO不友好

        四、發送請求

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

        項目:

        一、對密碼進行加密處理

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

        使用步驟:

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

        二、表單校驗規則

        在實際開發中,前后端都需要對表單的數據進行合法性的驗證,而且,后端做為數據合法性驗證的最后一個關口,在攔截非法數據方面,起到了至關重要的作用。使用第三方數據驗證模塊,來降低出錯率、提高驗證的效率與可維護性。

        步驟:

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

        三、四種常見的POST提交數據方式

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

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

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

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

        • 方式二:multipart/form-data

        常見的POST數據提交的方式。這種方式支持文件上傳,不過必須要設置form的enctyped等于這個值。使用multipart/form-data方式會生成了一個boundary 來分割不同的字段,為了避免與正文重復,boundary是一段很長的隨機拼接的字符串。然后Content-Type指明數據是以mutipart/form-data來編碼并包括進本次請求的boundary 值。消息主體最后以 –boundary–標示結束。

        • 方式三:application/json

        由于JSON規范的流行,現在越來越多的開發者將application/json這個Content-Type作為響應頭。用來告訴服務端消息主體是序列化后的JSON字符串。除了低版本IE之外各大瀏覽器都原生支持 JSON.stringify,服務端語言也都有處理JSON的函數,JSON能格式支持比鍵值對復雜得多的結構化數據,普通鍵值對中的值只能是字符串,而使用json,鍵值對可以重復嵌套。

        • 方式四:text/xml

        它是一種使用HTTP作為傳輸協議,XML作為編碼方式的遠程調用規范。不過后來使用很少。也許在十多年前,在json還未出來之前數據交互對接。

        總之application/x-www-form-urlencoded和multipart/form-data兩種POST方式都是瀏覽器原生支持的,是普遍使用的兩種方式,application/json是現在比較流行的新趨勢。

        四、multer

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

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

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

        實際網頁開發當中,我們前端需要向后端提交一些像mp4,mp3,圖片系列的東西,需要在后端進行接收。那么這里就可以使用Multer中間件來接收文件,對前端傳遞過來的文件做一些處理。

        1. multer是啥? Multer是Express官方推出的,用于node.js 處理前端以multipart/form-data請求數據處理的一個中間件。注意: Multer 不會處理任何非 multipart/form-data 類型的表單數據

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

        3. multer是一個中間件,我建議把這個中間件寫成一個單獨的文件,最后把配置好的multer實例暴露出去,在需要他的路由里面當作中間件去應用它。就可以很快捷的處理前端發送過來的文件。而無需每個文件都寫一遍。也更加符合我們模塊化編程的思想。下圖是我multer文件的配置。

        五、富文本編輯器

        富文本編輯器,Multi-function Text Editor, 簡稱 MTE, 是一種可內嵌于瀏覽器,所見即所得的文本編輯器。它提供類似于 Microsoft Word 的編輯功能,容易被不會編寫 HTML 的用戶并需要設置各種文本格式的用戶所喜愛。

        富文本編輯器不同于文本編輯器,程序員可到網上下載免費的富文本編輯器內嵌于自己的網站或程序里(當然付費的功能會更強大些),方便用戶編輯文章或信息。

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

        layui 富文本編輯器(layedit):

        • 使用:

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

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

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

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

        六、express-session

        (一)、Session簡單介紹
        session 是另一種記錄客戶狀態的機制,不同的是 Cookie 保存在客戶端瀏覽器中,而 session 保存在服務器上。Session的用途:
        session運行在服務器端,當客戶端第一次訪問服務器時,可以將客戶的登錄信息保存。
        當客戶訪問其他頁面時,可以判斷客戶的登錄狀態,做出提示,相當于登錄攔截。
        session可以和Redis或者數據庫等結合做持久化操作,當服務器掛掉時也不會導致某些客戶信息(購物車)
        丟失。

        (二)、Session的工作流程
        當瀏覽器訪問服務器并發送第一次請求時,服務器端會創建一個session對象,生成一個類似于
        key,value的鍵值對,然后將key(cookie)返回到瀏覽器(客戶)端,瀏覽器下次再訪問時,攜帶key(cookie),
        找到對應的session(value)。 客戶的信息都保存在session中。

        (三)、Cookie和Session區別:

        • cookie 數據存放在客戶的瀏覽器上,session 數據放在服務器上。

        • cookie 不是很安全,別人可以分析存放在本地的 COOKIE 并進行 COOKIE 欺騙 考慮到安全應當使用 session。

        • session 會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能 考慮到減輕服務器性能方面,應當使用 COOKIE。

        • 單個 cookie 保存的數據不能超過 4K,很多瀏覽器都限制一個站點最多保存 20 個 cookie。

        (四)、express-session的使用

        • 安裝 express-session:

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

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

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

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

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

        七、表單事件

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

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 久久91综合国产91久久精品| 国产精品99久久不卡| 2021最新国产精品一区| 欧洲精品色在线观看| 国产精品黄页免费高清在线观看| 国产精品日本一区二区不卡视频 | 久久无码精品一区二区三区| 国产亚洲精品一品区99热| 欧美精品欧美人与动人物牲交| 欧美精品综合视频一区二区| 99热精品毛片全部国产无缓冲| 3D动漫精品一区二区三区| 亚洲AV无码成人精品区蜜桃| 无码人妻一区二区三区精品视频 | 亚洲精品视频免费| 国产精品日日摸夜夜添夜夜添1国产精品va欧美精 | 午夜一级日韩精品制服诱惑我们这边| 国产成人亚洲综合无码精品| 亚洲国产精品无码久久SM | 国产a视频精品免费观看| 久久精品国产亚洲av麻豆色欲| 亚洲精品无码成人片在线观看| 久久精品国产清自在天天线| 国产精品午夜无码AV天美传媒| 最新国产精品亚洲| 亚洲精品在线观看视频| 欧美777精品久久久久网| 国产精品欧美亚洲韩国日本不卡| 国产精品成熟老女人视频| 国产精品揄拍100视频| 精品亚洲A∨无码一区二区三区| 无码精品日韩中文字幕| 少妇人妻偷人精品视频| 老司机亚洲精品影院无码| 精品国产一区二区三区不卡| 久久国产欧美日韩精品| 精品人妻系列无码天堂| 国产91精品在线观看| 精品一区二区三区中文字幕 | 乱精品一区字幕二区| 亚洲国产一二三精品无码|