前端小知识合集

目录

.map()

promise.all和promise.race

v-for中key的作用

vue.js中如果遇到非响应式数据,该怎么处理

什么叫响应式数据

$attrs 与 $listeners

vm.$attrs

vm.$listeners

.reduce()

vuerouter中的params 和query 的区别

.filter()

JavaScript中常用的选择器、节点获取

Object.defineProperty

javaScript中的正则表达式

addEventListener

bind、call、apply的区别

 js的replace()方法

Object.freeze()

基本使用 

Object.create()

react中static contextType

redux中store.subscribe

js可选链语法

socket.emit与socket.on

常用的 Mongoose 封装方法 

mongoose.lean()

MongoDB和Mongoose的区别

Sequelize

持久cookie

cookie与session

vue-router 3种重定向方式


.map()

.map() 是 JavaScript 中 Array 对象的一个方法,用于将数组中的每个元素映射到另一个数组中。它接受一个函数作为参数,该函数将每个元素作为输入并返回一个新的值,这些新的值被组成一个新的数组并返回。

例如,以下代码将数组中的每个元素乘以 2 并返回一个新的数组:

const arr = [1, 2, 3, 4];

const doubledArr = arr.map(num => num * 2);

console.log(doubledArr); // [2, 4, 6, 8]

在上面的代码中,map() 方法接受一个箭头函数作为参数,该函数将数组中的每个元素乘以 2 并返回新的值。这些新的值被组成一个新的数组,并存储在 doubledArr 变量中。


promise.all和promise.race

Promise.all() 和 Promise.race() 都是 Promise 对象的方法。

Promise.all() 接收一个由 Promise 对象组成的数组作为参数,返回一个新的 Promise 对象,该对象在数组中所有 Promise 对象都已经成功完成时才会被成功地解决。如果其中任何一个 Promise 对象被拒绝(rejected),则返回的 Promise 对象将被拒绝,并返回第一个被拒绝的 Promise 对象的错误信息。可以使用 Promise.all() 来并行运行多个 Promise 对象。

Promise.race() 接收一个由 Promise 对象组成的数组作为参数,返回一个新的 Promise 对象,该对象在数组中的任何一个 Promise 对象成功完成或被拒绝时立即被解决。如果任何一个 Promise 对象被解决,返回的 Promise 对象将与其状态相同。可以使用 Promise.race() 来创建一个超时效果或者只想获取最快的结果的情况。


v-for中key的作用

在 Vue.js 中,v-for 指令用于渲染列表,它可以遍历数组或对象的属性。在使用 v-for 渲染列表时,每个被渲染的元素都需要一个唯一的 key 属性。这个 key 属性的作用是为了提高列表的渲染性能

Vue.js 在更新 DOM 时,会尽可能地重用已经存在的元素,而不是从头创建新的元素。当 Vue.js 更新列表时,如果新旧列表中的元素存在相同的 key 值,那么 Vue.js 会认为它们是同一个元素,直接复用旧元素,而不是销毁旧元素然后创建新元素。这样做可以避免不必要的 DOM 操作,提高渲染性能。

如果没有 key 属性,Vue.js 就会使用默认的机制来维护列表元素的顺序和它们的身份,这样会导致性能下降,甚至出现意外的渲染结果。


vue.js中如果遇到非响应式数据,该怎么处理

在 Vue.js 中,只有被 Vue 实例所管理的数据才是响应式的,也就是说如果你使用了一些非响应式的数据,当这些数据发生变化时,Vue 的响应式系统并不会自动检测到这些变化,也就不会触发重新渲染。

如果你遇到了非响应式数据,可以考虑使用 Vue.set 或者 this.$set 方法来将其转化为响应式的数据。具体方法如下:

Vue.set(obj, key, value) 或者 this.$set(obj, key, value):这两个方法都可以将 obj 对象中的 key 属性的值设为 value,并且使这个新值是响应式的。如果 obj 是一个数组,key 应该是一个有效的数组索引。

如果你想将一个对象的所有属性都转化为响应式的,可以使用 Vue.observable 方法。这个方法可以接收一个对象作为参数,并且返回一个响应式的对象。但是需要注意的是,这个方法只在 Vue.js 2.6.0 及以上版本中可用。

总之,如果你遇到了非响应式数据,不要慌张,Vue.js 提供了很多方法来解决这个问题,你只需要选择一个合适的方法即可。


什么叫响应式数据

响应式数据是指当数据发生变化时,系统能够自动地对其进行更新,并使得所有依赖该数据的组件或页面都能够得到更新,从而保持数据的一致性。在前端开发中,响应式数据通常与框架(如Vue、React等)和状态管理库(如Vuex、Redux等)一起使用,以便更方便地管理和更新数据。响应式数据是一种非常重要的概念,因为它可以提高开发效率和用户体验。


$attrs 与 $listeners

vm.$attrs

2.4.0 新增

  • 类型{ [key: string]: string }

  • 只读

  • 详细

    包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

vm.$listeners

2.4.0 新增

  • 类型{ [key: string]: Function | Array<Function> }

  • 只读

  • 详细

    包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。


.reduce()

.reduce() 是 JavaScript 中的一个数组方法,用于对数组中的每个元素执行一个回调函数,并返回一个累加值。它的语法如下:

arr.reduce(callback[, initialValue])

其中:

callback:必需,要执行的函数。它接受四个参数:

accumulator:累加器,它累加回调函数的返回值。如果提供了 initialValue,则初始值为 initialValue,否则初始值为数组的第一个元素。

currentValue:当前元素。

currentIndex:当前元素的索引。

array:原始数组。

initialValue:可选,累加器的初始值。

例如,以下代码使用 .reduce() 方法计算数组 [1, 2, 3, 4] 的总和:

const arr = [1, 2, 3, 4];

const sum = arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);

console.log(sum); // 输出 10

vuerouter中的params 和query 的区别

在Vue中提供了两种方法来进行路由传参:query 和 params

query语法:

this.$router.push({path:"地址",query:{id:"123"}}); 这是传递参数

this.$route.query.id; 这是接受参数

params语法:

this.$router.push({name:"地址",params:{id:"123"}}); 这是传递参数

this.$route.params.id; 这是接受参数

不同之处:

  1. query 用path,params用name
  2. query的参数会显示在地址栏,params不会显示在地址栏
  3. params是路由的一部分,必须要有。query是拼接在url后面的参数,没有也没关系。
  4. params一旦设置在路由,params就是路由的一部分,如果这个路由有params传参,但是在跳转的时候没有传这个参数,会导致跳转失败或者页面会没有内容。
  5. params、query不设置也可以传参,但是params不设置的时候,刷新页面或者返回参数会丢失,query并不会出现这种情况

.filter()

filter用于对数组进行过滤
它创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意:filter()不会对空数组进行检测、不会改变原始数组

语法

Array.filter(function(currentValue, indedx, arr), thisValue)
  其中,函数 function 为必须,数组中的每个元素都会执行这个函数。且如果返回值为 true,则该元素被保留;
  函数的第一个参数 currentValue 也为必须,代表当前元素的值。

实例:过滤数组中大于5的元素

let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let res = nums.filter((num) => {return num > 5;});
console.log(res);  // [6, 7, 8, 9, 10]

JavaScript中常用的选择器、节点获取

getElementById: 通过元素的id属性获取元素节点,返回一个元素对象。

var element = document.getElementById("myId");
getElementsByTagName: 通过元素的标签名获取元素节点集合,返回一个包含所有匹配元素的HTMLCollection对象。
var elements = document.getElementsByTagName("div");
getElementsByClassName: 通过元素的class属性获取元素节点集合,返回一个包含所有匹配元素的HTMLCollection对象。
var elements = document.getElementsByClassName("myClass");
querySelector: 通过CSS选择器获取匹配的第一个元素节点,返回一个元素对象。
var element = document.querySelector("#myId .myClass");
querySelectorAll: 通过CSS选择器获取匹配的所有元素节点集合,返回一个包含所有匹配元素的NodeList对象。
var elements = document.querySelectorAll("div.myClass");


除此之外,还可以通过以下方式获取节点:

parentNode: 获取当前节点的父节点,返回一个元素对象。
var parent = element.parentNode;
childNodes: 获取当前节点的所有子节点,返回一个包含所有子节点的NodeList对象。
var children = element.childNodes;
firstChild: 获取当前节点的第一个子节点,返回一个元素对象。
var firstChild = element.firstChild;
lastChild: 获取当前节点的最后一个子节点,返回一个元素对象。
var lastChild = element.lastChild;
nextSibling: 获取当前节点的下一个兄弟节点,返回一个元素对象。
var nextSibling = element.nextSibling;
previousSibling: 获取当前节点的上一个兄弟节点,返回一个元素对象。
var previousSibling = element.previousSibling;


Object.defineProperty

Object.defineProperty() 是 JavaScript 中用于定义对象属性的方法。它允许我们定义一个新属性或修改现有属性的特性(比如值、可枚举性、可写性、可配置性)。其语法如下:Object.defineProperty(obj, prop, descriptor)

其中,obj 是要定义属性的对象,prop 是要定义或修改的属性名称,descriptor 是一个描述符对象,用于定义属性的特性。描述符对象包含以下可选属性:

value: 属性的值,默认为 undefined。

writable: 属性是否可写,默认为 false。

enumerable: 属性是否可枚举,默认为 false。

configurable: 属性是否可配置,默认为 false。

Object.defineProperty() 方法只能定义一个属性,如果要定义多个属性,需要多次调用该方法。
 


javaScript中的正则表达式

js正则标志/g,/i,/m说明

  • /g 表示该表达式将用来在输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个
  • /i  表示匹配的时候不区分大小写
  • /m 表示多行匹配,什么是多行匹配呢?就是匹配换行符两端的潜在匹配。影响正则中的^$符号

JavaScript 中可以使用正则表达式来匹配和操作字符串。下面是一些常用的正则表达式:

  1. 匹配数字:/\d/
  2. 匹配字母:/[a-zA-Z]/
  3. 匹配空白符:/\s/
  4. 匹配非空白符:/\S/
  5. 匹配单词字符(包括字母、数字和下划线):/\w/
  6. 匹配非单词字符:/\W/
  7. 匹配任意字符:/.+/
  8. 匹配邮箱地址:/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/
  9. 匹配 URL:/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/
  10. 匹配手机号:/^1[3456789]\d{9}$/

在 JavaScript 中,可以使用 test() 方法来测试一个字符串是否匹配某个正则表达式。例如:

const reg = /^1[3456789]\d{9}$/;
 const phoneNumber = '13812345678';
 if (reg.test(phoneNumber)) { 
    console.log('手机号格式正确'); 
} else { 
    console.log('手机号格式错误'); 
}

还可以使用 exec() 方法在字符串中搜索匹配的内容,并返回第一个匹配结果。例如:

const reg = /\d+/g; 
const str = 'abc123def456ghi789'; 
let matchResult; 
while ((matchResult = reg.exec(str))) { 
    console.log(matchResult[0]); 
// 输出匹配的数字 }

以上只是一些常用的正则表达式和用法,JavaScript 中还有很多其他的正则表达式语法和方法,需要根据具体需求进行学习和使用。


addEventListener

addEventListener 是 JavaScript 中的一个函数,用于在 DOM 元素上绑定事件。它接受三个参数:

  • 事件类型(如 "click","mouseover")
  • 事件处理函数
  • 事件参数(可选)

示例 

document.getElementById("myBtn").addEventListener("click", function(){ 
alert("Button was clicked"); });

在这个示例中,当页面中的按钮被点击时,会弹出一个消息框,显示 "Button was clicked"。


bind、call、apply的区别

fn.call(thisArg, arg1, arg2, arg3, ...)
apply(thisArg, [argsArr])
bind(thisArg, arg1, arg2, arg3, ...)

 1、相同点

  • 三个都是用于改变this指向;
  • 接收的第一个参数都是this要指向的对象;
  • 都可以利用后续参数传参。

2、不同点

  • call和bind传参相同,多个参数依次传入的;
  • apply只有两个参数,第二个参数为数组;
  • call和apply都是对函数l立即调用,而bind方法不会立即调用函数,而是返回一个修改this后的函数,调用方法bind(thisArg, arg1, arg2, arg3, ...)( )。

 js的replace()方法

js中是没有replaceAll方法,一次只能替换一个

使用具有全局标志g的正则表达式

var str = "dogdogdog";

var str2 = str.replace(/dog/g,"cat");

console.log(str2);

输出结果为:catcatcat。这里实现替换全部匹配字符串。

使用另一种具有全局标志g的正则表达式的定义方法

例子:

var str = "dogdogdog";

var str2 = str.replace(new RegExp("dog","gm"),"cat");

console.log(str2);

输出结果为:catcatcat。这里g表示执行全局匹配,m表示执行多次匹配。
 


Object.freeze()

const定义基本数据类型,这个值是不可以修改的

如果想要一个对象不能被修改,可以使用Object.freeze()

它的作用是冻结一个对象,被冻结的对象有以下几个特性:

  • 不能添加新属性
  • 不能删除已有属性
  • 不能修改已有属性的值
  • 不能修改原型
  • 不能修改已有属性的可枚举性、可配置性、可写性

基本使用 

Object.freeze(obj)

由于Object.freeze() 只支持浅冻结,所以如果遇到对象中包含对象,那么只能冻结最外层的对象。

不过可以封装一个深冻结

function deepFreeze(obj) {
    var propNames = Object.getOwnPropertyNames(obj)
    propNames.forEach(item => {
        var prop = obj[item]
        if (prop instanceof Object && prop !== null) {
            deepFreeze(prop)
        }
    })
    return Object.freeze(obj)
}

模拟Object.freeze()原理主要用到两个关键方法,Object.definedProperty()、Object.seal()。


Object.create()

语法Object.create(proto[,propertiesObject])

参数 

  • proto
    • 创建对象的原型,表示要继承的对象
  • propertiesObject(可选 )
    • 也是一个对象,用于对新创建的对象进行初始化

 先看看底层代码实现:

Object.create =  function (o) {
    var F = function () {};
    F.prototype = o;//将新对象f的原型指向原对象o
    return new F();//返回新对象f
  };

作用创建一个基于原对象作为原型的新对象


react中static contextType

static contextType 是在 React 中使用 context 的一种方式。它是一个类属性,可以指定一个 context 对象,使得这个组件可以访问到该 context 对象提供的数据。使用 static contextType 后,可以在组件中使用 this.context 来访问到 context 对象中的数据。免去了繁琐的Consumer

例如,如果有一个名为 MyContext 的 context 对象,可以在组件中这样使用:

import React from 'react';
import MyContext from './MyContext';

class MyComponent extends React.Component {
  static contextType = MyContext;

  render() {
    const { someData } = this.context;
    return <div>{someData}</div>;
  }
}

在上面的例子中,MyComponent 组件通过 static contextType 指定了要使用的 context 对象是 MyContext。然后在 render 方法中,可以通过 this.context 来访问到 MyContext 中的数据。


redux中store.subscribe

store.subscribe() 是 Redux 中的一个函数,用于订阅 store 的变化。当 store 中的 state 发生变化时,订阅函数会被调用。一般情况下,我们可以在订阅函数里调用 store.getState() 来获取最新的 state,然后根据最新的 state 进行相应的操作。

例如,我们可以使用 store.subscribe() 来更新 UI,以反映 Redux store 中的最新状态。当 store 中的数据发生变化时,订阅函数会被调用,我们就可以在订阅函数中更新 UI。

示例代码:

import { createStore } from 'redux';

function counterReducer(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default:
      return state;
  }
}

const store = createStore(counterReducer);

store.subscribe(() => {
  console.log(store.getState());
});

store.dispatch({ type: 'INCREMENT' }); // 打印 1
store.dispatch({ type: 'INCREMENT' }); // 打印 2
store.dispatch({ type: 'DECREMENT' }); // 打印 1

js可选链语法

可选链语法是一种 JavaScript 中的语法,用于方便地访问可能不存在的属性或方法,避免了出现 TypeError 的情况。以下是常用的可选链语法:

?. 在对象属性或方法后面加上问号,表示如果该属性或方法存在,才会执行后面的操作,否则返回 undefined。

const user = { 
name: 'Alice', 
address: { city: 'Shanghai', street: 'Nanjing Rd' } 
}; 
console.log(user?.address?.city); // 输出 'Shanghai' 
console.log(user?.address?.zipcode); // 输出 undefined

?? 用于判断一个变量是否为 null 或 undefined,如果是则返回一个默认值。

const name = null;
console.log(name ?? 'Unknown'); // 输出 'Unknown'

const age = 18;
console.log(age ?? 'Unknown'); // 输出 18

?.[] 用于访问数组中的元素,如果数组不存在或者数组越界,则返回 undefined。

const arr = [1, 2, 3]; 
console.log(arr?.[0]); // 输出 1 
console.log(arr?.[3]); // 输出 undefined

socket.emit与socket.on

socket.emitsocket.on 是 Socket.IO 中的两个重要函数,用于在客户端和服务器之间进行实时通信。

socket.emit 用于向服务器发送消息,其语法如下:

socket.emit(eventName, data, callback);

其中,eventName 表示要发送的事件名称,data 表示要发送的数据,callback 表示发送成功后的回调函数(可选)。

示例代码:

// 发送消息
socket.emit('chat message', 'Hello, World!', function() {
  console.log('消息发送成功!');
});

socket.on 用于监听服务器发送过来的消息,其语法如下:

socket.on(eventName, callback);

其中,eventName 表示要监听的事件名称,callback 表示事件触发后的回调函数。

示例代码:

// 监听消息
socket.on('chat message', function(msg))

常用的 Mongoose 封装方法 

连接 MongoDB 数据库:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/myapp', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

定义模型:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const UserSchema = new Schema({
  name: String,
  age: Number,
});

const User = mongoose.model('User', UserSchema);

创建文档:

const user = new User({ name: 'Alice', age: 26 });
user.save();

查询文档:

User.findOne({ name: 'Alice' }, (err, user) => {
  console.log(user);
});

更新文档:

User.updateOne({ name: 'Alice' }, { age: 27 }, (err, res) => {
  console.log(res);
});

删除文档:

User.deleteOne({ name: 'Alice' }, (err, res) => {
  console.log(res);
});

除了以上基本操作,还可以封装一些常用的操作,例如:

分页查询:

const query = User.find().skip((pageNum - 1) * pageSize).limit(pageSize);
const users = await query.exec();

根据条件查询:

const query = User.find({ age: { $gt: 20 } });
const users = await query.exec();

统计数量:

const count = await User.countDocuments({ age: { $gt: 20 } });

排序:

const query = User.find().sort({ age: -1 });
const users = await query.exec();

聚合查询:

const result = await User.aggregate([
  {
    $match: { age: { $gt: 20 } },
  },
  {
    $group: {
      _id: '$name',
      total: { $sum: 1 },
    },
  },
]);

以上是一些常用的 Mongoose 封装方法,可以根据实际需求进行封装和扩展。


mongoose.lean()

mongoose.lean() 方法是用于将 MongoDB 查询结果转换为 JavaScript 对象的方法。调用该方法可以获得更快的查询速度和更低的内存消耗,因为它不会将查询结果转换为 Mongoose 文档对象。而是直接返回普通的 JavaScript 对象,这些对象不具备 Mongoose 的实例方法和实例属性,但是可以直接使用 JavaScript 对象的方法和属性。

使用 lean() 方法的示例代码:

const User = mongoose.model('User');
const users = await User.find().lean();

在上面的代码中,User.find().lean() 返回的是一个普通的 JavaScript 数组,而不是 Mongoose 的文档对象数组。这样可以避免不必要的内存消耗和性能损失。但是需要注意的是,由于返回的对象不是 Mongoose 的文档对象,因此不能直接调用 Mongoose 的实例方法和实例属性。


MongoDB和Mongoose的区别

MongoDB是一种开源的、面向文档的非关系型数据库管理系统,它使用JSON风格的文档代替了传统的行和列的存储方式。而Mongoose是一个Node.js的ORM框架,它提供了一些基于Schema的方法,使得我们可以在Node.js中更加方便地操作MongoDB数据库。

具体来说,MongoDB和Mongoose的区别主要体现在以下几个方面:

  1. 数据库结构:MongoDB是面向文档的数据库,它的数据结构是以文档形式存储的,每个文档可以有不同的字段和数据结构。而Mongoose则是基于Schema进行存储,Schema是一种数据结构,描述了每个文档中包含哪些字段以及字段的数据类型。

  2. 数据类型:MongoDB支持的数据类型比较简单,包括字符串、整数、浮点数、日期等基本数据类型,以及数组和嵌套文档等复杂数据类型。而Mongoose支持的数据类型更加丰富,包括枚举、正则表达式、缺省值等。

  3. 数据验证:Mongoose提供了Schema验证机制,可以在保存数据之前对数据进行验证,验证不通过则无法保存。而MongoDB本身并没有提供数据验证功能。

  4. 查询方式:MongoDB提供了强大的查询和聚合功能,可以进行复杂的数据查询和计算。而Mongoose在查询方面比较简单,主要是通过一些基本的查询方式来进行数据查询。

综上所述,MongoDB和Mongoose在很多方面都有所不同,但它们都是非常优秀的技术,可以帮助我们更好地管理和操作数据。


Sequelize

Sequelize是一个Node.js ORM(Object-Relational Mapping)框架,支持多种数据库,包括MySQL、PostgreSQL、SQLite和MariaDB等。它提供了一种在Node.js中操作关系型数据库的简单方式,使用JavaScript语言进行操作,可以方便地进行增删改查等操作。

Sequelize主要提供了以下功能:

  1. 定义模型:Sequelize提供了一种定义模型的方式,可以方便地将JavaScript对象映射到数据库中的表,并设置表之间的关系。

  2. 数据查询:Sequelize提供了一种查询构建器,可以方便地进行复杂的查询操作,并支持事务和锁机制。

  3. 数据验证:Sequelize提供了一种数据验证机制,可以在保存数据之前对数据进行验证。

  4. 数据迁移:Sequelize提供了一种数据迁移工具,可以方便地进行数据库结构的变更,支持回滚操作。

总的来说,Sequelize是一个功能丰富、易于使用的ORM框架,可以帮助我们更好地操作关系型数据库。它提供了一种简单的方式来定义模型、查询数据、验证数据和迁移数据等操作,使得我们可以更加高效地进行数据库开发。


持久cookie

  • 持久 Cookie 是通过设置 Cookie 的过期时间来实现的。即在设置 Cookie 的时候,可以通过指定过期时间让该 Cookie 在指定时间之前一直有效。一般情况下,持久 Cookie 的过期时间是比较长的,比如几天、几周、几个月甚至几年。在客户端每次请求服务器时,会将该 Cookie 一同发送到服务器端,使得服务器可以识别该客户端的身份信息,并且可以在该 Cookie 未过期的情况下保持登录状态。

  • 以下是使用 Node.js 和 Express 框架实现持久 Cookie 的代码示例:

    const express = require('express');
    const app = express();
    
    // 设置持久 Cookie
    app.get('/set-cookie', (req, res) => {
      res.cookie('username', 'John Doe', { maxAge: 30 * 24 * 60 * 60 * 1000 }); // Cookie 过期时间为 30 天
      res.send('Cookie 已设置');
    });
    
    // 获取持久 Cookie
    app.get('/get-cookie', (req, res) => {
      const username = req.cookies.username;
      if (username) {
        res.send(`欢迎回来,${username}`);
      } else {
        res.send('您还未登录');
      }
    });
    
    app.listen(3000, () => {
      console.log('应用已启动');
    });

    在上面的示例中,我们通过 res.cookie() 方法设置了一个名为 username 的 Cookie,它的过期时间为 30 天。在接下来的请求中,我们可以通过 req.cookies.username 来获取该 Cookie 的值。这样,我们就可以实现持久 Cookie 功能了。


cookie与session

每一个session创建之后,都会存储到cookie中,JSESSIONID的属性中

session的创建:

用户第一次访问时,会创建一个Session对象,并且会给该Session对象一个id,该Id 会被带回页面,存储到Cookie中的JSESSIONID属性中。

之后用户的每一次访问都会将Cookie中的JSESSIONID传到服务器,服务器会通过该id获取到对应的session对象,如果能获取到对象,则继续使用该对象,如果不能获取到Session对象,则会新建一个Session对象。

如果Cookie中的JSESSIONID没有值或者没有JSEESIONID这个属性,则会访问服务器时,服务器会直接创建一个session对象。

session到期:

Session的生命周期到期,默认为30分钟,Session生命周期到期之后Session对象会被回收。

Session对象被注销,Session对象被注销之后Session对象会被回收。

注:关闭浏览器,并不会主动注销Session,也不会回收Session对象,而是清空Cookie中的JSESSIONID的值。下次访问时没有Session的id传递过去,故而获取不到Session对象,会创建一个Session对象。


vue-router 3种重定向方式

  • this.$router.push():跳转到指定url路径,并向history栈中添加一条记录,点击后退会返回到上一个页面;
  • this.$router.replace():跳转到指定url路径,但是history栈中不会有记录(即直接替换成当前页面),点击返回,跳转到上个页面的前一个页面;
  • this.$router.go(n):向前或向后跳转n个页面,n可为正整数或负整数。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值