zoukankan      html  css  js  c++  java
  • 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信息

     
  • 相关阅读:
    Docker的安装和scrapy-splash的安装
    scrapyd打包到服务器运行
    一些python的简单有用方法
    NFS学习
    apache配置https加密传输
    httpd基于域名不同的虚拟主机配置
    Openssl创建私有CA
    NODEJS版本控制和切换
    HyperV使用Centos系统安装FTP服务
    装Anaconda报错This Python interpreter is in a conda environment, but the environment has not been activated. Libraries may fail to load. To activate this environment please see http://conda.io/activation
  • 原文地址:https://www.cnblogs.com/xiaozhumaopao/p/11105621.html
Copyright © 2011-2022 走看看