当前位置: 首页 > news >正文

class11:cookie和session

目录

  • 一、子路由ajax跳转页面
  • 二、分解为MVC结构
  • 三、cookie
    • 1. 前端cookie
    • 2. 后端cookie
      • 2.1 后端设置cookie发送给前端
      • 2.2 前端cookie自动发送给后端
    • 3. res.cookie方法
  • 四、session
  • 五、自动登录
    • 1. 注册登录
    • 2. 自动登录
    • 3. 后端完整代码

一、子路由ajax跳转页面

ajax是请求数据的,不是用来跳转的页面的,如果想要ajax请求来跳转页面,在后端返回数据的时候再进行跳转页面。

// index.html
<body>
    <h2>静态页面</h2>
    <input type="text" id="text"></input>
    <button id="but">发送</button>

    <!-- 静态文件夹 默认带有后端的http://localhost:端口 -->
    <script>
        but.onclick=()=>{
            // 跳转新页面
            window.location.href = "/" + text.value; 
        }
    </script>
</body>

index.html为静态文件夹public中的文件,window.location.href 可跳转到指定页面,/为静态文件夹 默认带有后端的路由:http://localhost:端口,再拼接上输入的路由后缀,得到子路由并跳转。

// app.js
const express = require("express");
const app = express();
const ejs = require("ejs");
app.listen("3000", ()=>{console.log("3000端口已启动");});
app.use(express.static("./public"));
app.set("view engine", "ejs");

app.get("/:id", (req, res)=>{
    res.render("index", {
        arr: req.params.id,
    });
    console.log("id:", req.params.id);
});

app.js中配置静态页面,通过http://localhost:3000访问,在index.html输入框中输入内容点击按钮访问,后端收到并返回数据(前端输入的参数),同时跳转到相应的ejs页面。

// index.ejs
<body>
    ejs页面
    <%= arr %>
</body>

ejs为views文件夹中的文件,跳转到ejs页面,输出返回的参数,即html输入的内容。

测试:访问路由http://localhost:3000,输入子路由后缀ppp,跳转到相应ejs页面。
在这里插入图片描述

二、分解为MVC结构

我们把上一节的跳转页面分为MVC结构:

新建controlles文件夹并新建controlles.js页面:

自定义一个方法parmsaRour用于app.js发起请求返回数据跳转页面,把该方法导出以便其他文件引入:

// controlles.js
const parmsaRour = (req, res) => {
    let dataFile = req.params.id;
    res.render("index", {
        arr: req.params.id,
    })
};

module.exports={
    parmsaRour,
}

在app.js中引入自定义方法parmsaRour并使用:

// 引入自定义模块
const {parmsaRour} = require("./controlles/controlles");  // 控制层模块

app.get("/:id", parmsaRour);

测试:
在这里插入图片描述

然后我们把上一课以分为MVC结构的计算偶数实例嵌入这个例子可得到:

// 主目录app.js
const express = require("express");
const app = express();
const ejs =require("ejs");
app.listen("3000");
// 请求自定义模块
const {parmsaRour} = require("./controlles/controlles");  // 控制层模块

//设置ejs文件
app.set("view engine","ejs");

// 静态资源
app.use(express.static("./public"));

// 设置前端请求地址
app.get("/:id",parmsaRour);

modules模块:

// exitstFile.js
const fs = require("fs");
const path = require("path");

// 判断文件是否存在
const tend =(val)=>{
    // 获取文件的绝对路径
    let fileDataPath = path.resolve(__dirname, "../data/"+val+".txt");
    // 判断文件是否存在
    let bol = fs.existsSync(fileDataPath)
    return {
        bol,
        fileDataPath
    }
};

// 写入数值
const writeParams = (arr,fileDataPath)=>{
    fs.writeFile(fileDataPath, JSON.stringify(arr),()=>{
        console.log("写入成功")
    })
};

module.exports ={
    tend,
    writeParams
};
// math.js
const mathParams =(val)=>{
    let arr =  [];
    for (let i=0;i<=val;i++){
        if(i%2 ===0){
            arr.push(i);
        };
    };
    return arr
};

module.exports ={
    mathParams
};

views模块:

// index.ejs
<body>
    <h2>ejs页面</h2>
    <%= arr %>
    <!--输出node输入到ejs中的数据-->
    <!-- views 只放置 ejs文件   -->
</body>

controlles模块:

// controlles.js
// 控制数据文件
const {tend,writeParams}  = require("../modules/exitstFile");  // 判断文件是否存在和写入模块
const {mathParams} = require("../modules/math");// 计算数值模块
const fs = require("fs");

const parmsaRour = (req,res)=>{
    let dataFile = req.params.id;
    let {fileDataPath, bol} = tend(dataFile); // 传文件名进行判断:返回绝对路径和文件判断(是否存在同名文件)
    // 有文件就读取,没有则计算数字并写入
    if(bol){  // 有就是true
        // 有就直接读取文件
        fs.readFile(fileDataPath, (err, arr)=>{ 
            res.render("index",{
                arr:arr
            })
        })
    }else{  // 没有文件
        // 计算数值
        let arr =  mathParams(dataFile);
        // 写入文件
        writeParams(arr, fileDataPath);
        //跳转到index.ejs页面  渲染页面
        res.render("index",{
            arr:arr
        })
    }
};

module.exports ={
    parmsaRour
};

三、cookie

1. 前端cookie

**document.cookie **可以获取浏览器中设置的cookie值,同时也是设置的值。

cookie的位置:控制台 Application 下面的cookies中。

前端cookie会根据ajax请求自动发送到后端的。后端 -> 前端 -> 后端

在这里插入图片描述

**前端写入cookie: ** document.cookie =“属性名=属性值”

例:在控制台设置document.cookie = “name = lebron”,输入document.cookie回车得到自己设置的cookie:

在这里插入图片描述

2. 后端cookie

2.1 后端设置cookie发送给前端

设置cookie:res.cookie(“属性名”,“属性值”)

app.get("/www", (req, res)=>{
    res.cookie("name", "zxunLuo");
    res.send("返回cookie");
})

在这里插入图片描述

注意: 如果前端获取不到cookie,则先安装插件cookie-parser并引入使用:

// 下载安装
npm install cookie-parser --save

// 引入使用
var cookieParser = require('cookie-parser');

// 引入cookieParser中间件
app.use(cookieParser());

2.2 前端cookie自动发送给后端

当后端设置cookie并把cookie发给前端后,当前端发起ajax请求时,会自动把cookie带入请求头一起发送给后端:

// ./public/index.html
<body>
    <h2>静态页面</h2>
    <button id="but">cookie发送</button>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        but.onclick=()=>{
            axios({
                method:"get",
                url:"/yyy"
            });
        }
    </script>
</body>
// app.js
app.get("/yyy", (req, res)=>{
    res.send("前端请求头携带cookie");
})

在这里插入图片描述

3. res.cookie方法

官网:Express 4.x - API 参考 (expressjs.com)

res.cookie(name, value [, options])

options属性和类型:

domain cookie 的域名。默认为应用的域名。

encode 用于cookie 值编码的同步函数。默认为encodeURIComponent

httpOnly 布尔值 前端不能访问

maxAge 设置cookie过期时间,时间一到自动删除cookie 自动登陆使用的

path cookie的路径。默认为“/”。 后端设置的指定路由才能获取到数据

secure 布尔值 只能https能够访问。true只能在https协议下使用 false 可以在http协议使用

signed 布尔值 指示是否应该对 cookie 进行签名

四、session

npm相关说明:express-session - npm (npmjs.com)

express-session 是一种cookie的使用,数据存在后端。

安装:

npm install express-session

引入和配置:

const session = require('express-session')
// 返回给前端的数据格式
app.use(session({
    secret: 'keyboard cat',    // cookie的标识
    resave: false,             // 是否覆盖并修改并行的两个请求
    // true只能在https协议下使用 false 可以在http协议使用
    saveUninitialized: true,   // 初始化时是否保存---在前端读取页面时候就发送给前端并保存前端
    cookie: {   // 设置返回的cookie
        secure: false,
        maxAge: 100000
    }
}));

设置与获取:

// session配置
app.get("/qaq", (req, res) => {
    req.session.Fluo = "我见青山多妩媚"; // 设置session
    res.send("qaq:");
});

app.get("/qqq", (req, res) => {
    console.log("qqq:", req.session.Fluo);  // 获取session
    res.send("qqq:" + req.session.Fluo);
});

先访问/qaq设置session,再访问/qqq获取session:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、自动登录

1. 注册登录

首先写一个正常的注册登录,前端点击登录后把用户信息user、pas发给后端,后端收到后设置session并返回数据,前端收到数据跳转页面使登录成功。

// public/index.html
<body>
    <h2>静态页面</h2>   
    <button id="wrap">谁登陆了</button>
    <div id="box">
         账号<input type="text" id="txt"> <br/>
         密码<input type="text" id="pas">
         <button id="but">登陆</button>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        //登陆注册
        but.onclick = () => {
            axios({
                method: "post",
                url: "/qwe",
                data: {
                    user: txt.value,
                    pas: pas.value
                }
            }).then(data => {
                box.style.display = "none";
                wrap.innerHTML = data.data.value;
                console.log("data:", data);
            })
        };
    </script>
</body>

在这里插入图片描述

代码说明:在浏览器访问本地3000端口的路由,输入账号user和密码pas,点击登录触发按钮事件,前端发起axios请求,并携带参数user和pas给后端,后端返回数据后,前端跳转页面显示登录成功。这里为了简单,跳转页面变成了将页面样式清空(box.style.display = “none”;)并显示该用户注册成功的字样(wrap.innerHTML = data.data.value;)。
在这里插入图片描述

后端在收到前端的axios请求后,首先用user和pas设置成它的session,然后返回数据,返回的数据中包括code码,表示设置session成功,还有value,其值为user与"注册成功"拼接的字符串,用于显示在html页面。

app.post("/qwe", (req, res) => {
    console.log(req.body)
    req.session.luoxb = req.body;   // 设置session
    // 返回数据
    res.send({
        code: 1,
        value: req.body.user + "注册成功"
    });
});

打印输出我们在前端输入的用户信息:
在这里插入图片描述

2. 自动登录

如果已经注册登录过,那下一次我们重新进入入口路由(http://localhost:3000)时可以自动登录。做法就是当访问入口路由时,立即发起一个axios请求,判断后端是否存在登录过的记录,这个记录就是session,判断session是否有值;若有值返回的data中的code为1,则返回session值的用户账号给前端,前端则跳转至登录成功页面,这里的跳转页面同第一小节正常登录的跳转一样简单化为清除样式并显示自动登录成功字样;若session没有值,返回的data中的code为0,则让前端显示"账号已过期,请重新登录。"

// public/index.html
axios({
	method: "get",
	url: "/cook",
}).then((data) => {
    if(data.data.code == 1){
        console.log("自动登录成功:", data);
        box.style.display = "none";
        wrap.innerHTML = data.data.value;
	}else if(data.data.code == 0){
        console.log("账号过期或未登录:", data)
        wrap.innerHTML = data.data.value;
	}
})
// app.js
app.get("/cook", (req, res) => {
    if (req.session.luoxb) {
        res.send({
            code: 1,
            value: req.session.luoxb.user + "自动登录成功",
        })
    } else {
        res.send({
            code: 0,
            value: "账号已过期,请重新登录。",
        })
    }
    console.log("自动登录,获取session:", req.session.luoxb);  // 获取session  时间一旦后端没有办法获取到数据
});

注意:因为自动登录是页面加载时就立即发起axios请求,但是未登录前是没有session的,此时session为undefined

在这里插入图片描述

在第一次登录成功后,可以在session有效时间内自动登录,重新访问入口路由或刷新页面,页面都会自动登录,显示某用户自动登录成功。此时获取session成功。

在这里插入图片描述

在这里插入图片描述

注意: 如果是第一次访问入口路由或手动删除cookie或cookie过期,则显示:
在这里插入图片描述

3. 后端完整代码

const express = require("express");
const app = express();
app.listen("3000");
app.use(express.urlencoded({ extend: true }));
app.use(express.json());
// 静态资源
app.use(express.static("./public"));

// 引入session 设置自动登陆
const session = require('express-session');
// 返回给前端的数据格式
app.use(session({
    secret: 'keyboard cat', // cookie的标识
    resave: false,  // 是否覆盖并修改并行的两个请求
    // true只能在https协议下使用 false 可以在http协议使用
    saveUninitialized: true,    // 初始化时是否保存在前---端读取页面时候就发送给前端并保存前端
    cookie: {   // 设置返回的cookie
        secure: false,
        maxAge: 100000
    }
}));

// session配置
app.post("/qwe", (req, res) => {
    console.log(req.body)
    req.session.luoxb = req.body;   // 设置session
    // 返回数据
    res.send({
        code: 1,
        value: req.body.user + "注册成功"
    });
});

app.get("/cook", (req, res) => {
    if (req.session.luoxb) {
        res.send({
            code: 1,
            value: req.session.luoxb.user + "自动登录成功",
        })
    } else {
        res.send({
            code: 0,
            value: "账号已过期,请重新登录。",
        })
    }
    console.log("自动登录,获取session:", req.session.luoxb);  // 获取session  时间一旦后端没有办法获取到数据
});

// app.use中的是默认值,里面是没有数据的,前端发送给后端的时候也是空值,后端就没有办法获取数据
// 前端进入对应设置的路由里面,那就会进行设置,设置完成只要前端的cookie不过期就不会删除,后端就能获取到对应的数据

相关文章:

  • 一些常用的刷题网站
  • Python自动化小技巧11——excel文件的文字内容筛选
  • ArrayList的源码分析
  • 不支持TLS的设备如何实现游客登录加密通信方案
  • 【Pandas 数据分析3-2】Pandas 数据读取与输出 - Excel
  • TiDB Dashboard 实例性能分析 - 持续分析页面
  • Spring Boot 集成 Redis 配置 MyBatis 二级缓存
  • 9 二叉树-添加
  • SSM进阶-搭建Dubbo
  • STM32F103 CAN通讯实操
  • JAVA-----注释、字面量、关键字、制表符
  • numpy数组的变形、级联操作、聚合操作、常用的数学函数以及矩阵相关
  • ActiveMQ(二)
  • 某大学ipv6和ipv4结合的校园网规划设计
  • 【程序员表白大师】html七夕脱单必看源码制作
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • centos安装java运行环境jdk+tomcat
  • Git的一些常用操作
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • PHP CLI应用的调试原理
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • Terraform入门 - 3. 变更基础设施
  • ucore操作系统实验笔记 - 重新理解中断
  • Vue ES6 Jade Scss Webpack Gulp
  • WinRAR存在严重的安全漏洞影响5亿用户
  • Zepto.js源码学习之二
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 检测对象或数组
  • 实现菜单下拉伸展折叠效果demo
  • 数组大概知多少
  • 找一份好的前端工作,起点很重要
  • 移动端高清、多屏适配方案
  • ​LeetCode解法汇总518. 零钱兑换 II
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • %check_box% in rails :coditions={:has_many , :through}
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (31)对象的克隆
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (接口封装)
  • (离散数学)逻辑连接词
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (转) Face-Resources
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)