国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > Nodejs網(wǎng)站登錄以及Redis使用開(kāi)發(fā)

Nodejs網(wǎng)站登錄以及Redis使用開(kāi)發(fā)

時(shí)間:2023-05-25 01:18:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-05-25 01:18:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)

Nodejs網(wǎng)站登錄以及Redis使用開(kāi)發(fā):
對(duì)于后端開(kāi)發(fā)了解并不多或者只會(huì)用js開(kāi)發(fā)頁(yè)面效果的小伙伴來(lái)說(shuō),要開(kāi)發(fā)一款真正屬于自己的網(wǎng)站或者APP不用Node來(lái)開(kāi)發(fā)服務(wù)器實(shí)在是太可惜啦,因?yàn)镹odejs能夠在很短的時(shí)間內(nèi)開(kāi)發(fā)出網(wǎng)站必要的服務(wù)端接口API。使用Nodejs開(kāi)發(fā)最先就是要安裝Nodejs, 這里提供Nodejs官網(wǎng):
一 、Nodejs介紹

Nodejs是一個(gè)javascript運(yùn)行環(huán)境,運(yùn)行在服務(wù)端作為web server, 通常前端開(kāi)發(fā)人員都知道的ECMAScript是js官網(wǎng)的標(biāo)準(zhǔn), 寫js和nodejs都必須要遵守,這里面包括了變量定義,循環(huán),判斷,函數(shù),但是ECMAScript不能夠操作DOM,不能監(jiān)聽(tīng)事件,不能發(fā)送ajax請(qǐng)求,不能處理http請(qǐng)求,也不能操作文件等等。

前端js ECMAScript + WebAPI (DOM操作 BOM操作 事件綁定 Ajax等)

Nodejs ECMAScript + NodeAPI (處理http,處理文件等server端的操作)

二、server端開(kāi)發(fā)事項(xiàng)

1、服務(wù)穩(wěn)定性和安全

server端可能會(huì)遭受各種惡意攻擊和誤操作,比如說(shuō)防止sql注入引起mysql表發(fā)生問(wèn)題,xss攻擊客戶端,或者后端代碼本身的問(wèn)題,如果是單個(gè)客戶端可以意外掛掉,但是服務(wù)器不能,所以可以使用pm2做進(jìn)程守護(hù)(進(jìn)程掛掉會(huì)自動(dòng)重啟)

2、考慮CPU和內(nèi)存(優(yōu)化,擴(kuò)展)

客戶端獨(dú)占一個(gè)瀏覽器,內(nèi)存和CPU都不是問(wèn)題, 而server端要承載很多請(qǐng)求,CPU和內(nèi)存都是很稀缺的資源,要考慮到使用stream寫日志和redis存session。

3、日志記錄

前端也會(huì)參加寫日志,但只是日志的發(fā)起方并不關(guān)心后面的問(wèn)題,而server端要記錄日志,存儲(chǔ)日志,分析日志,前端并不用太關(guān)心過(guò)程。

4、集群和服務(wù)拆分

這個(gè)要結(jié)合產(chǎn)品的發(fā)展方向和用戶量的多少來(lái)決定,服務(wù)器需要多少流量,需要多少機(jī)器來(lái)拆分流量的問(wèn)題要具體看軟件開(kāi)發(fā)公司的業(yè)務(wù)需求來(lái)定奪,但不管怎么樣也是服務(wù)端需要考慮的開(kāi)發(fā)問(wèn)題之一.

三、了解http請(qǐng)求的全過(guò)程(從url輸入到接口返回步驟)

首先需要了解的是TCP三次握手: 1.客戶端DNS解析獲取IP地址,是否可用。 2.服務(wù)端告知客戶端可用。 3.客戶端再次告知服務(wù)端ok,會(huì)訪問(wèn)。

通過(guò)三次握手客戶端才會(huì)發(fā)送http請(qǐng)求到服務(wù)端,服務(wù)端接收到http請(qǐng)求處理并返回結(jié)果,客戶端接收到返回?cái)?shù)據(jù),并且處理數(shù)據(jù)(渲染頁(yè)面并執(zhí)行js)

了解到這些基本的http請(qǐng)求后,我們就可以自己搭建個(gè)最普通的http請(qǐng)求啦

const http = require('http');const server = http.createServer((req, res) => { res.setHeader('content-type','application/json'); res.end(JSON.stringify({ errno: 0, data: [1,2,3] }));});server.listen(8000)三、nodejs http請(qǐng)求獲取方式

這里主要介紹GET和POST請(qǐng)求獲取客戶端參數(shù)的方式,首先是GET方法獲取參數(shù)方式

const querystring = require('querystring')const server = http.createServer((req, res) => { const data = []; res.setHeader('content-type','application/json'); // 獲取 path const url = req.url req.path = url.split('?')[0] // 解析 query // http://localhost:8000/api?a=1&b=2 req.query = querystring.parse(url.split('?')[1]) if (req.method==='GET' && req.path === '/api') { res.end(JSON.stringify({ errno: 0, data: req.query // { a:1, b:2 } })); }});server.listen(8000) 其次是POST方法獲取參數(shù)方式,由于nodejs中獲取POST方法是異步的,所以要先執(zhí)行獲取POST參數(shù),就必須先執(zhí)行該方法,于是就引入了ES6的Promise對(duì)象來(lái)定義。

// 用于處理 post data 之后有這個(gè)函數(shù)的引入const getPostData = req => { const promise = new Promise((resolve, reject) => { //后面的操作能夠保證req.body是一個(gè)空對(duì)象 if (req.method !== 'POST') { resolve({}) return } if (req.headers['content-type'] !== 'application/json') { resolve({}) return } let postData = '' //異步方法 req.on('data', chunk => { postData += chunk.toString() }) //異步方法 req.on('end', () => { if (!postData) { resolve({}) return } resolve( JSON.parse(postData) ) }) }) return promise}四、cookie使用方法和session的引入

客戶端訪問(wèn)服務(wù)端的時(shí)候,服務(wù)端要首先保證客戶端的訪問(wèn)者是登錄狀態(tài)下進(jìn)行的操作,所以在訪問(wèn)的時(shí)候都需要進(jìn)行登錄校驗(yàn)以及登錄信息的存儲(chǔ),此時(shí)我們就能使用cookie來(lái)解決這個(gè)問(wèn)題。

何為cookie呢?cookie是存儲(chǔ)在瀏覽器的一段字符串,通常是以鍵值對(duì)形式存在(最大為5kb), cookie擁有跨域不共享的機(jī)制(如果做到了跨域共享,那么對(duì)于其他網(wǎng)站來(lái)說(shuō),內(nèi)部信息泄露對(duì)網(wǎng)站安全受影響很大,瀏覽器肯定屏蔽這種漏洞存在),通??蛻舳苏麄€(gè)cookie傳到服務(wù)端格式結(jié)構(gòu)如下:k1=v1;k2=v2;k3=v3,每次發(fā)送http請(qǐng)求,會(huì)將請(qǐng)求域的cookie一起發(fā)送給server, server可以修改cookie并返回給瀏覽器, 瀏覽器也可以通過(guò)js修改cookie(有限制,服務(wù)端可以設(shè)置httpOnly來(lái)限制客戶端的修改)

cookie的Nodejs獲取辦法

const cookieStr = req.headers.cookie; req.cookie = {} if (cookieStr) { cookieStr.split(';').forEach(item => { const arr = item.split('=') const key = arr[0].trim() const value = arr[1].trim() req.cookie[key] = value }); } 我們通過(guò)上述代碼方式將客戶端的cookie存入req.cookie的對(duì)象當(dāng)中,如果cookie的值需要修改或者新增,依據(jù)如下代碼便能夠?qū)崿F(xiàn):

// 獲取 cookie 的過(guò)期時(shí)間const getCookieExpires = () => { const d = new Date() d.setTime(d.getTime() + (24 * 60 * 60 * 1000)) return d.toGMTString()}//代碼默認(rèn)cookie存儲(chǔ)時(shí)間為一天res.setHeader('Set-Cookie', `username=${username};path=/;httpOnly;expires=${getExpireData()}`) 不知道很多小伙伴看到這段代碼后,是不是發(fā)現(xiàn)雖然cookie能夠?qū)崿F(xiàn)cookie客戶端和服務(wù)端正常的交互功能了,但是username這個(gè)信息對(duì)于開(kāi)發(fā)各類網(wǎng)站的開(kāi)發(fā)人員來(lái)說(shuō),太過(guò)敏感了,很多客戶是不希望暴露自己的用戶名給所有人看,而且從安全的角度來(lái)說(shuō)非常危險(xiǎn),通常網(wǎng)站登錄注冊(cè)只要用戶名密碼,等于一半的信息被別人掌握了,所以要避免這個(gè)問(wèn)題就引入了session這種方式來(lái)作為服務(wù)端判斷用戶登錄校驗(yàn)的一種方式。

let SESSION_LOGIN = {}let sessionId= req.cookie.sessionId;if (sessionId) { if (!SESSION_LOGIN[sessionId]) { SESSION_LOGIN[sessionId] = {} } } else { needSetCookie = true userId = `${Date.now()}_${Math.random()}` SESSION_LOGIN[sessionId] = {} } req.session = SESSION_LOGIN[sessionId] 這種方式看似好像實(shí)現(xiàn)了服務(wù)端存儲(chǔ)session的方式,也同時(shí)避免了客戶端直接傳遞username的困擾,但是一個(gè)服務(wù)器進(jìn)程下,一個(gè)SESSION_LOGIN對(duì)象存儲(chǔ)所有用戶的cookie操作是非常不現(xiàn)實(shí)的,一方面服務(wù)端SESSION_LOGIN對(duì)象內(nèi)存會(huì)溢出,無(wú)法存儲(chǔ)過(guò)多數(shù)據(jù)(一個(gè)進(jìn)程內(nèi)分配的內(nèi)存有限),而且在生產(chǎn)環(huán)境中基本都是采用多進(jìn)程的環(huán)境,而多進(jìn)程環(huán)境下客戶端每次訪問(wèn)的服務(wù)端進(jìn)程又不確定(負(fù)載均衡的問(wèn)題,所以面對(duì)這樣的問(wèn)題一個(gè)對(duì)象明顯不能作為我們存儲(chǔ)用戶信息的方式,此時(shí)我們想到了使用redis內(nèi)存數(shù)據(jù)庫(kù)的方式。

redis作為web server最常用的緩存數(shù)據(jù)庫(kù),數(shù)據(jù)放在內(nèi)存中,相比于mysql,訪問(wèn)速度快(內(nèi)存和硬盤不是一個(gè)數(shù)量級(jí)的),但是成本更高,因?yàn)閮?nèi)存存儲(chǔ)成本高于硬盤,并且可存儲(chǔ)的數(shù)據(jù)量也會(huì)更小(內(nèi)存的硬傷), 將web server和redis拆分成兩個(gè)單獨(dú)的服務(wù)雙方都是獨(dú)立的,都是可擴(kuò)展的(例如可以擴(kuò)展成一個(gè)集群)。

這是關(guān)于redis如何存儲(chǔ)服務(wù)器的部分實(shí)現(xiàn)代碼

let sessionId = req.cookie.sessionId;let needSetCookie = false;if (!sessionId ) { needSetCookie = true; sessionId = `${Date.now()}_${Math.random()}` //將sessionId 設(shè)置到redis數(shù)據(jù)庫(kù)中 set(sessionId , {}) } req.sessionId = sessionId; //從redis中通過(guò)sessionId作為redis的key獲取value get(req.sessionId).then(sessionData => { if (sessionData == null) { //將sessionId 設(shè)置到redis數(shù)據(jù)庫(kù)中 set(sessionId , {}) req.session = {} } else { //存入req對(duì)象中可以為之后登錄驗(yàn)證判斷做準(zhǔn)備 //登錄驗(yàn)證從redis獲取的內(nèi)容信息sessionData={ username:'xxx', realname:'xxx' } req.session = sessionData } //返回獲取post參數(shù)的promise對(duì)象進(jìn)行下一步操作 //剛才的post參數(shù)獲取方式 return getPostData(req) }) //之后可以繼續(xù)執(zhí)行關(guān)于存入postData的操作 .then(postData => { req.body = postData; .... } session適合使用redis的原因主要有幾點(diǎn):

1.session訪問(wèn)繁忙,對(duì)性能要求極高。

2.session可不考慮斷點(diǎn)丟失數(shù)據(jù)的問(wèn)題(內(nèi)存的硬傷)

3.session數(shù)據(jù)量一般不會(huì)太大(相比于mysql來(lái)說(shuō)太小了)

目前個(gè)人博客更新至此,后面內(nèi)容盡情期待

關(guān)鍵詞:使用

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉