NodeJS開發博客(三) 數據的保存


什么是cookie

存儲在瀏覽器的一段字符串(最大5k)

跨域不共享

格式如 k1=v1 k2=v2 因此可以存儲結構化數據

每次發送http請求,會將請求域的cookie一起發送給server

server 可以修改 cookie 並返回給瀏覽器

瀏覽器也可以通過 JS 修改 cookie (有限制)

參考 lesson5;

 

---

session方法

首先解釋何為 seesion【注意和 sessionStorage做區別】

首先,我大致的知道,session是一次瀏覽器和服務器的交互的會話,會話是啥呢?就是我問候你好嗎?你回恩很好。就是一次會話,那么對話完成后,這次會話就結束了,還有我也知道,我們可以將一個變量存入全部的$_SESSION['name']中,這樣php的各個頁面和邏輯都能訪問到,所以很輕松的用來判斷是否登陸。

 
這是我之前理解的session,當然也是對的,只是解釋的太膚淺,理解的太表面了,面試官如果聽到這樣的答案其實是不太滿意的。我參考了其他的很多資料,徹底理解清楚session。
 
在說session是啥之前,我們先來說說為什么會出現session會話,它出現的機理是什么?我們知道,我們用瀏覽器打開一個網頁,用到的是HTTP協議,學過計算機的應該都知道這個協議,它是無狀態的,什么是無狀態呢?就是說這一次請求和上一次請求是沒有任何關系的,互不認識的,沒有關聯的。但是這種無狀態的的好處是快速。
 
所以就會帶來一個問題就是,我希望幾個請求的頁面要有關聯,比如:我在www.a.com/login.php里面登陸了,我在www.a.com/index.php 也希望是登陸狀態,但是,這是2個不同的頁面,也就是2個不同的HTTP請求,這2個HTTP請求是無狀態的,也就是無關聯的,所以無法單純的在index.php中讀取到它在login.php中已經登陸了!
 
那咋搞呢?我不可能這2個頁面我都去登陸一遍吧。或者用笨方法這2個頁面都去查詢數據庫,如果有登陸狀態,就判斷是登陸的了。這種查詢數據庫的方案雖然可行,但是每次都要去查詢數據庫不是個事,會造成數據庫的壓力。
 
所以正是這種訴求,這個時候,一個新的客戶端存儲數據方式出現了:cookie。cookie是把少量的信息存儲在用戶自己的電腦上,它在一個域名下是一個全局的,只要設置它的存儲路徑在域名www.a.com下 ,那么當用戶用瀏覽器訪問時,php就可以從這個域名的任意頁面讀取cookie中的信息。所以就很好的解決了我在www.a.com/login.php頁面登陸了,我也可以在www.a.com/index.php獲取到這個登陸信息了。同時又不用反復去查詢數據庫。
 
雖然這種方案很不錯,也很快速方便,但是由於cookie 是存在用戶端,而且它本身存儲的尺寸大小也有限,最關鍵是用戶可以是可見的,並可以隨意的修改,很不安全。那如何又要安全,又可以方便的全局讀取信息呢?於是,這個時候,一種新的存儲會話機制:session 誕生了。
 
我擦,終於把session是怎么誕生的給圓清楚了,不容易啊!!!
 
好,session 誕生了,從上面的描述來講,它就是在一次會話中解決2次HTTP的請求的關聯,讓它們產生聯系,讓2兩個頁面都能讀取到找個這個全局的session信息。session信息存在於服務器端,所以也就很好的解決了安全問題。
 
--------
 session 保存數據的問題:
 
 
 
解決方案:
web server 最常用的緩存數據庫,數據存放在內存中;
相比於 mysql,訪問速度快 內存和硬盤不是一個數量級的
但是成本高,可存儲的數據量小(內存的硬傷)
 

 

 

 

安裝 redis

 

 

mac:訪問  https://brew.sh/index_zh-cn ,執行


/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

就能安裝上 brew
執行 redis-server
然后新打開終端執行 redis-cli


最基本的命令:
set myname lihua
get myname
keys * //可以看到當前所有的key
del myname //刪除key
目的: nodejs 連接 redis 的demo;  封裝成工具函數,可以供 API 使用
首先啟動 redis: redis-server 端口是 6379

新建一個項目,npm init
然后 安裝redis: npm i redis --save
新建index文件:
const redis = require('redis')
//創建客戶端
const client = redis.createClient(6379,'127.0.0.1');

client.on('error',err=>{
    console.error(err)
})
//redis.print 會在執行完命令后打印出是否正確
client.set('myname','zhangsan2',redis.print)
client.get('myname',(err,val)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log('val:',val);
    client.quit()
})

執行 node index.js 

然后可以啟動 redis-cli 查看 get myname

============================

接下來開始操作原來的博客項目,首先安裝 redis: npm i redis -save
詳見代碼。

===========================
和前端聯調

 

 

首先npm install http-server -g
http-server -p 8001 //設置端口

===================

nginx介紹:

 

 



 

 以上是mac命令,對於windos如下:

1 首先修改配置文件  sudo vi /usr/local/etc/nginx/nginx.conf 

1) 修改 端口為 8080

server{
  listen  8080;
  server_name localhost  
}

 

2)

location / {
   proxy_pass http://localhost:8001;  
}

location /api/ {
   proxy_pass http://localhost:8000;  
   proxy_set_header Host $host;
}

最后執行 wq 保存退出

然后啟動  nginx 

訪問http://localhost:8080/ 就可以訪問到 localhost:8001 的html

訪問的接口api 就訪問到了 localhost:8000的api

【所以要同時啟動 服務端8000;客戶端8001;nginx的服務;redis的服務】【沒有啟動8080的,但是通過nginx,可以通過8080訪問其他端口】

[注意:如果接口訪問不到 請注意排查一下是不是接口寫的是post,而你用的是get請求]

 

=========

最后 一些小修改:

admin.html 中,由於只能訪問自己的頁面:

 
let url = '/api/blog/list?isadmin=1' // 增加一個 isadmin=1 參數,使用登錄者的用戶名,后端也需要修改 !!!
 
let author = req.query.author || '';
      let keyword = req.query.keyword || '';
      //新增admin部分
      if(req.query.isadmin){
        const loginCheckResult = loginCheck(req);
        if(loginCheckResult){
          //未登陸
          return loginCheckResult
        }
        // 強制查詢自己的博客,也就是說有這個參數的時候,不在使用url上給到的usernam
        // 而是使用當前登陸信息中的 username
        author = req.session.username
      }

 

 ===============
至此,根據分支:trunk.lesson7---是服務端代碼 執行npm run dev 運行在 8000端口
分支 trunk.htmls---是客戶端代碼,執行http-server -port 8001 運行在 8001端口 // 或者 http-server -p 8001
開啟 nginx服務,配置了8080端口,和代理8000與8001的接口,可以訪問 8080端口
開啟redis服務,可以存儲相應的 redis數據
 
 
 
//app.js中的session和cookie和redis的配置
const session = require('koa-generic-session');
const redisStore = require('koa-redis');
const { REDIS_CONF } =require('./conf/db');

app.keys=['keys'];
app.use(session({
  cookie:{
    httpOnly:true,
    path:'/',
    maxAge:24*60*60*1000
  },
  store:redisStore({
    all:`${REDIS_CONF.host}:${REDIS_CONF.port}`
  })
}))

//給session賦值的時候,會觸發 生成cookie
ctx.session.username = ctx.request.body.username;

cookie-->session-->redis
瀏覽器和服務器通過cookieid獲取到session
保存的session通過app中的配置,會把session保存到redis中,同時會生成一個cookieid;
通過cookied可以獲取到所有的session信息

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM