• 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信息

     
  • 相关阅读:
    Longest Palindromic Substring
    PayPal MLSE job description
    Continuous Median
    Remove Duplicates From Linked List
    Valid IP Address
    Longest substring without duplication
    Largest range
    Subarray sort
    Multi String Search
    Suffix Trie Construction
  • 原文地址:https://www.cnblogs.com/xiaozhumaopao/p/11105621.html
Copyright © 2020-2023  润新知