验证json-web-token的koa中间件:koa-jwt
前言
JSON Web Token(以下简称JWT)是一个开放标准,它定义了一种紧凑且自包含的方式,用于作为JSON对象在各方之间安全地传输信息。此信息可以被验证和信任,因为它是数字签名的。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对来签名。简而言之,就是使用一个加密的以及base64编码组成的字符串,用于解决跨域认证问题的一个机制!
传统的用户认证流程
传统的用户认证流程一般如下:
用户想服务器端发送用户名以及密码;
服务器端认证通过后,将用户信息存储于当前会话(session)中,比如有用户信息、登录时间等等;
服务器端向用户返回一个sessionId,写入到用户的cookie中;
随后用户的每一次请求,都会通过cookie来携带上sessionId,传回给服务器,告知已认证通过,并进行认证通过许可后的资源访问;
服务器从cookie中捞到sessionId之后,认证通过后,放行继续往下执行;
😕 这里方式是拥有一定的弊端的,加入是单机的,一般没有什么太大的问题,但是如果是集群或者是跨域多服务的情况下,就需要将sessionId来进行共享, ...
koa用户认证抽象层中间件
前言
koa-userauth用户认证抽象层中间件,主要用于在某些场景下,某些资源是必须授权(一般是登录)通过之后才能够访问的,当未登录去访问需要的资源时,由于该资源是需要授权才能够访问到的(可选择从session中获取),因此将自动重定向到,再重定向到原本目标资源的访问
如何使用123456789101112131415161718const koa = require('koa');const userauth = require('koa-userauth');const session = require('koa-generic-session');const app = new koa();app.keys['I am secret'];app.use(session());app.use(userauth({ match: '/user', loginURLFormatter: (url) => { return '即将重定向的登录页面?redirect=' + url }, getUser: async ctx => { const t ...
文件上传中间件:koa-multer
前言
文件上传,应该是web应用开发中最常见的动作了,一般有单文件上传、多文件上传、文件与数据一同上传等方式,而koa中使用了koa-multer来进行文件的上传服务,下面让我们来了解一波关于文件上传服务的使用!
如何使用123456789101112131415161718192021222324252627const Koa = require('koa');const Router = require('@koa/router');const multer = require('@koa/multer');const app = new Koa();const router = new Router();const upload = multer({}); // 这里可以通过传递参数来控制文件上传的配置// 以下是定义的文件上传路由router.post('/upload-multiple-files', upload.fields([ { name: 'avatar', maxCount: 1 }, { name: 'boop', maxCount: 2 }]), ct ...
外部存储会话管理:koa-generic-session
前言
之前我们介绍了关于koa-session的简单运用,了解了其中关于内存缓存级别(cookies)控制的客户端会话管理,现在我们来了解一波关于外部存储(koa-redis)的相关运用,来以免服务重启导致缓存数据丢失的问题!这里的koa-generic-session其实就是针对原本的koa-session进行一个一层包装,通过追加的固定的配置以及对应额外的属性来丰富这个session原本提供的功能!这里可以简单的理解是将原本应该存储在内存中的数据,现在都存储到了数据库,而且数据结构就是以简单的key: value键值对的方式来存储的,如下图所示
如何使用12345678910111213141516171819202122232425const session = require('koa-generic-session');const redisStore = require('koa-redis');const koa = require('koa');const app = new koa();app.keys = ['自定义keys'];app.use(session({ ...
会话管理中间件:koa-session
前言koa-session官网
对于浏览器端的session,通常会使用cookie来存储session标识。在用户首次访问服务端时,服务端会生成一个唯一的session标识,并将其存储在cookie中返回给浏览器。随后,每次浏览器发送请求到服务端时,会自动携带上一次存储在cookie中的session标识。服务端通过解析请求中的session标识,可以识别出当前请求属于哪个session。服务端会根据session标识来查找相应的session数据,并进行相应的处理。在处理完请求之后,服务端会更新session数据,并将最新的session标识返回给浏览器,以便下次请求使用。这种基于cookie的session机制可以确保同一个浏览器在一次会话中持续保持与服务端的连接,并共享会话数据。通过每次请求携带最新的session标识,可以保证同一个session会话的持续性和一致性。此外,为了防止篡改或伪造session标识,可以结合使用签名(sig)等方式,增加session的安全性。Koa简单的会话管理中间件,基于cookie机制,并支持外部存储(比如redis、db数据库等存储方式) ...
路由配置中间件:koa-router
前言koa-router官网
Koa自身并没有提供关于对于不同的path、不同的method的处理中间件配置,假如我们在程序中采用一系列if判断,来识别不同的路径、不同的请求方式对应于不同的中间件函数的话,那么随着项目的迭代,产生的结果将会是毁灭性的!!因此,需要 🈶 那么一个中间件,能够帮助我们管理好不同的路径、不同的请求方式下对应的中间件:koa-router,通过koa-router,可以满足这个情况的同时,还能够满足路由的叠加、嵌套,下面让我们来一一剖析一波!
如何使用12345678910const Koa = require('koa');const Router = require('@koa/router');const app = new Koa();const router = new Router();router.get('/', (ctx, next) => { // ctx.router available});app .use(router.routes()) .use(router.allowedMethods());
这里我们 � ...
解析请求body中间件:koa-bodyparser
前言bodyparser官网
作为消息请求体(body)的解析器,基于co-body进行的body的解析,可支持json、form、text、xml类型的body的解析!在处理程序之前,在中间件中解析传入的请求体,解析完成后,将在Koa上下文ctx.request中追加body参数,使得后续所有的中间件可以通过ctx.request.body属性来访问到解析后的参数,从而获取请求参数!!
如何使用12345678const Koa = require('koa');const bodyParser = require('@koa/bodyparser');const app = new Koa();app.use(bodyParser({}));app.use(ctx => { ctx.body = ctx.request.body console.info(ctx.request.rowBody)})
🌠 上述代码是bodyparser的简单运用,通过bodyParser函数的运行结果(应该是接收ctx+next作为参数的函数),来作为响应的中间,这里bodyPars ...
koa的使用与常用中间件一览
前言Koa官网
Koa,基于Node.js平台的下一代web开发框架!致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。通过利用 async 函数,Koa`` 帮你丢弃回调函数,并有力地增强错误处理。 Koa`` 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。
koa是什么?
Koa 应用程序是一个包含一组中间件函数的对象,它是按照类似堆栈的方式组织和执行的。Koa 类似于你可能遇到过的许多其他中间件系统,例如 Ruby 的 Rack ,Connect 等,然而,一个关键的设计点是在其低级中间件层中提供高级“语法糖”。这提高了互操作性,稳健性,并使书写中间件更加愉快。这包括诸如内容协商,缓存清理,代理支持和重定向等常见任务的方法。尽管提供了相当多的有用的方法 Koa 仍保持了一个很小的体积,因为没有捆绑中间件。
如何使用koa?123456const Koa = require('koa');const app = new Koa();app.use(async ctx => { ctx.bo ...
vue源码学习与分析(三):vue指令
前言
在编写vue项目的过程中,指令应该是相当的熟悉的了Vue 指令是一种特殊的 HTML 属性,具有 v- 前缀,用于在模板中声明性地绑定数据并对 DOM 进行操作。指令可以被绑定到 HTML 元素、组件和相应的模板语法中。在 Vue 中,指令本质上就是实现了一个自定义操作的 JS 函数,该函数接受两个参数:绑定元素 (el) 和指令对象 (binding)。指令对象包含了一些指令相关的信息,例如指令名称、表达式、修饰符等。
官方的v指令都有哪些
官方指令一览
指令
描述
条件指令
用于做条件渲染,包括整个if家庭(v-if、v-else、v-else-if)
v-text
用于对整个节点赋值文本内容
v-html
用于更新元素的innerHTML
v-show
用于切换一个元素的显示与隐藏
v-for
类似于array.map(),用于将一个列表数据转换为元素列表
v-on
缩写:@,用于捆绑事件监听
v-bind
缩写::,用于将变量与属性进行捆绑,使得属性参数化
v-model
在表单控件或者组件上创建双向绑定
v-slot
缩写 ...
vue-router的用法与源码学习
前言
在之前vue全家桶项目中,对于vue-router的使用,爽得不要不要的,😕 那么,我们是否有思考过,这个vue-router的工作过程是怎样的?它是如何设计的?为什么我们简单通过配置一张“路由表”,就可以实现整个web应用的路由控制功能?在路由表中它与component组件的关联是如何被建立起来的?懒加载机制是如何实现的?为什么在任意组件中通过watcher $route就可以自动检测到路由发生了变化,并触发监听函数的?这个RouterView究竟是何方神圣,凭什么它能够“装载”component,并让component按照自身的钩子函数去执行?👇 将通过分析vue-router的源码执行过程,顺带resolve这些问题!
Vue Router 是 Vue.js (opens new window)官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
嵌套的路由/视图表
模块化的、基于组件的路由配置
路由参数、查询、通配符
基于 Vue.js 过渡系统的视图过渡效果
细粒度的导航控制
带有自动激活的 CSS class 的链 ...
Vuex的用法与源码学习
前言
在使用vue全家桶来开发前端站点的时候,对于vue组件间通信,有那么一种方式(也是普遍使用的方式),就是使用vuex来实现跨组件间的通讯,本文章旨在通过使用vuex解决实际项目的同时,从源码层面解析关于vuex是如何做到远程触发的相关原理的!Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。🌠 从上面可以看出这个vuex的工作流是单向的,主要包含有3个元素:
状态(state): 驱动应用的数据源;
视图(view): 以声明方式将状态映射到视图;
操作(action): 响应在视图上的用户输入导致的状态变化
🌠 而实际在使用过程中,vuex的设计理念是:把组件的共享状态抽取出来,以一个全局单例模式管理,组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为
Vuex的一般用法
😕 这里的一般流程如下:
源码分析
😕 这个Store对象是如何被“植入到”vue实例中的呢?为什么可以在vue实例中就 ...
vue源码学习与分析(五):业界关于vue使用过程中提升性能的编码习惯
前言
业界网络上关于提升vue编程 🈶 不少的编程技巧,而且之前自己更多的是拿来就直接用了,也不清楚为什么需要这样子写?在学习了关于vue的源码之后,觉得很有必要来针对这些优化技巧提供适当、合理的一个解释!
👇 是关于网络上所提及的关于提升vue编程性能的一些小技巧:
在使用v-for指令进行循环的时候,需要针对每一个item提供对应唯一的key作为属性,这样子可以提供渲染的性能;
合理使用 v-if 和 v-show:v-if 在条件为 false 时会完全销毁元素及其事件监听器和子组件,而v-show 只是简单地隐藏元素。因此,在频繁切换一个元素的显示状态时,应该使用 v-show;
避免在模板中使用复杂表达式:复杂的表达式会增加渲染的时间,可以把计算逻辑放到 computed 或者 methods 中;
合理使用计算属性和 watch:计算属性具有缓存机制,只有在依赖的变量发生变化的时候才会重新计算,而 watch 监听变量的变化,当变量发生变化时就会触发函数执行;
采用异步组件和路由懒加载:将一个大型应用拆分成小块,并根据需要动态加载可以提高应用的性能;
合理使用 v- ...
vue源码学习与分析(二):vue中的监听机制
前言
网络上充斥着一堆的看法,说这个vue是一个MVVM的前端框架,将双向数据绑定做了很好的实现。😕 那么,什么是双向数据绑定?我们有必要学习这个双向数据绑定吗?vue是如何实现双向数据绑定的?为什么vue中的数据一更新,界面就会对应发生变化?👇 我们带着着几个问题,来理解vue的双向数据绑定的过程,从更加深层次的角度来理解关于vue的一个执行过程,以便于自己后续在实际的项目coding过程中弄清一系列场景,编写更好的代码!
两种监听数据的方式
在学习了关于vue的相关源码(v2.7.x)之后,发现其中原来存在着两种完全不一样的数据监听方式:
通过 data 对象来实现数据响应式;
使用 Watcher 对象来监听数据变化😕 那么这两种数据监听方式有什么区别呢?
数据监听方式
模式
触发机制
通过 data 对象来实现
自动配置,框架集成
通过Object.defineProperty()方法的回调来触发
使用 Watcher 对象来监听
手动配置,灵活运用
通过proxy机制
重要元素
在开始进行数据监听流程分析之前,需要先了解一下相关的角色元素,方 ...
vue源码学习与分析(一):vm实例如何渲染
前言
接着上一篇文章,关于new Vue({})脚本程序执行的时候发生了什么?为什么执行了这个方法之后,就可以对应在界面上展示相应的信息(如下图所示)
🌟 猜想:一个html需要在界面上展示对应的渲染结果,那么需要对应的添加相应的html标签,才可能使对应的节点元素能够正常展示!
👉 那么,问题就演变为Vue是如何生成对应的html出来的?
要想了解这个渲染的过程,需要先了解一下相关的概念,方便后续直接深入了解vue的渲染过程!!!
理解相关的元素
虚拟节点: VNode
创建虚拟节点: createElement
虚拟节点: VNode
*vnode是一个虚拟节点对象,用于描述组件树上的一个节点,包含了节点的名称(tag)、节点属性信息(data)、子节点(children)*,主要将原本在html中可视化的节点信息,抽象为虚拟的节点(带一定的数据结构在其中),在vue环境中,我们仅需要操作这个VNode即可,而无需直接去操作dom!!😕 为什么要将普通的html的dom操作,转换为VNode的操作??
👉 因为直接操作dom是一个耗性能的过程,对一个dom节点的 ...
vue源码学习与分析
前言
终于来开始对vue源码进行一个完整的剖析学习了!根据整体的源码分析,整理了以下 👇 一个关于vue源码的学习计划:🌠 这里分为几个阶段来对vue源码进行解读与学习!
vue源码学习;
vue-cli脚手架学习;
vue全家桶vuex、vue-router学习;
vue-loader学习
👽 这边将从本文章以及后续的其他文章中记录关于vue源码的一个学习过程,从源码的角度来理解这样子设计的一个目的!
源码整体剖析
从比较大的角度来理解源码,并分析源码的一个运行执行过程,提炼其中的关键参与成员!
一切从new Vue({})开始
😕 👇 一个最简单的程序的运行
12345678910111213141516171819202122232425262728293031<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <d ...
html中的picture是如何使用的
前言
今天偶然遇到这个picture标签,平时在日常的业务开发过程中,比较少使用到该节点,查阅了MDN官方的文档, 🐈 才知道存在着另外一种图片媒体资源标签:通过<picture>标签来包含一个或者多个<source>元素和一个<img>元素,来为不同的显示设备/场景提供对应的图像版本!也就是说,可单纯直接通过html标签以及它的属性,来实现一个“自动媒体查询”的图像效果!!!如下图所示;
12345<picture> <source srcset="https://interactive-examples.mdn.mozilla.net/media/cc0-images/surfer-240-200.jpg" media="(orientation: portrait)"> <img src="https://interactive-examples.mdn.mozilla.net/media/cc0-images/painted-hand-298-332.jpg" alt=""& ...
搭建vue源代码调试的两种方式
前言
在开始进行vue的源码阅读之前,可以先download下来关于vue的相关源代码,:thinking_face: 如果我能够在实际的项目中通过vue的断点调试,来跟踪程序的运行执行过程,那么会是一个很好的方式来理解vue的设计与执行过程!本文章将介绍两种不同的调试技巧,可以在实际的过程中各取所需!
官方源码调试通过执行 👇 的命令
1npm run dev
将启动一个开发服务,其实就是将源码进行打包(包含debugger指令),输出到一js文件中,然后在项目中引用该js文件,即可实现源码调试,如下图所示:
自定义的跨项目源码调试
🌠 上述的调试方式是将所有的代码都打到一个js中,然后使用对应的js进行调试的,那么是否有那么一种方式,可以保留源码结构,然后又可以进行方便的调试的呢?答案是可以的!😕 在平时的项目开发过程中,🈶 那么一种代码依赖关联技巧,就是借助于npm的本地化依赖机制,将原本一个远程库的依赖,改变为一个本地库的依赖,采用本地源码依赖的方式,那么是否也可以如法炮制,将vue源码的调试,集成到本地源码中,然后在断点中进行对应的源码调试呢? 👇 就来常识这种方 ...
eslint+stylelint+prettier+husky+commitlint+vscode实现vue编码规范自动化管理
前言
在日常的coding编码过程中,难免会遇到其他的同事的编码并没有严格按照入职时的编码规范来严格编码,导致项目中的代码混乱无序,没有按照一定的规则规范,使得最终的整个项目不是完整的一个项目,因此,很有必要将所有的童鞋的编码习惯以及编码风格给统一起来,但又不想直接通过阅读代码的方式以及强制要求的方式要限定统一的规格!eslint + stylelint + prettier + husky + vscode = 编码规范自动化
相关的概念介绍
在开始介绍搭建完整的过程之前,先简单介绍一下相关的成员以及他们对应的使用场景!
eslint
主要负责代码规则校验,具体可以参考之前的一篇文章: ESLint的用法!
stylelint
主要负责监测样式规则,具体可以参考之前的一篇文章:stylelint的用法!
prettier
prettier 是一种代码格式化工具,它可以自动帮助开发者规范化代码结构、缩进、换行等细节问题,使代码更加整洁、易读、易维护。prettier 支持多种编程语言,包括 JavaScript、TypeScript、CSS、HTML、JSON 等。通过使用 P ...
vue单页转多页优化实战
前言
在实际的vue正常项目迭代过程中,随着日常业务的正常迭代,存在 🈶 那么些场景需要快速访问的页面,减少白屏时间,提升用户体验,比如像一些中间状态页面、跳转页面、动态化因此政策相关文件等等!需要在vue项目的基础上,提供这样子的一个配置,假如直接就 🆕 一个组件作为路由来使用的话,将会加载到不必要的其他js,因此需要将项目进行多页应用转换,说白了就是生成多个html文件,不同的html文件代表着不同的SPA入口,而不同的SPA又可以共用同一套实现逻辑!!因此,本文章将从单页转多页,并记录其中的优化过程,以免后续踩坑!
原本的单页应用的方式1vue create bundle-test
使用官方的脚手架创建vue全家桶项目(vue2.0+系列),并执行npm run serve命令,启动对应的前端服务☝ 上面这里的路由懒加载机制,是vue脚手架自带的,可减少js的包过大的原因,关于这个路由的懒加载原理,之前在学习webpack的相关知识点的时候已经具体阐述了,可以在之前的文章webpack动态导入实现懒加载机制
🌠 细心的朋友可以发现,在访问这个站点的时候,浏览器预先加载了a ...
husky是如何实现自动化代码管理的
前言
在日常的代码管理中,没有严格按照代码规范来编写代码,提交的git message不规范,很难从提交日志中看出调整了什么内容,其他同事使用的ide与我的不一致,其他同事与我的编码有空格冲突,又不能一口气直接替换,花费大量的时间来进行代码的合并,解决空格冲突等等,我们的编码工作,不应该是在这个重复的低效的工作上的!!👉 因此,**husky(哈士奇)**就闪亮 🌠 登场了!😕 第一次听到这个中文翻译时,有些许疑惑,按照 官方文档 所描述的!当您提交或推送时,您可以使用它来整理您的提交消息、运行测试、lint 代码等
什么是husky?
当您提交或推送时,您可以使用它来整理您的提交消息、运行测试、lint 代码等这个是官方的介绍,husky支持所有的git勾子,实际在使用的过程中,除了这个勾子动作之外,应该还可以支持到npm的相关勾子动作
如何使用husky(npm方式)husky-init是用husky快速初始化项目的一次性命令!
1npx nusky-init && npm install
☝ 上述这里的命令,将设置husky,同时修改package.js ...