blog-frontend
blog-frontend copied to clipboard
Vue3+Vite+ElementPlus实现的个人博客,包含GitlabCI、Docker、Nginx、docker-compose相关配置
## SSO SSO的核心意义就是一句话:**一处登录,处处登录;一处注销,处处注销**,并且,此处的"一" 指的都是单点登录系统,"处处"指的都是各个子系统,后文中单点登录系统使用`SSO_server`替代, 子系统使用`SSO_client`替代。 需要补充的是,`SSO_server`几乎是一个纯后端的内容(仅仅需要管理一个登录页面),而`SSO_client` 则是包含了前后端等业务逻辑:) ## 动作分解一:一处登录 全局中**只有单点登录系统持有完整的用户信息表**,所有的登录都由`SSO_server`完成,包括登录页面也由`SSO_server`持有 + 流程一:当用户访问`SSO_client`中的某项资源(可能是前端的某个路由,也可能是某个接口)被`SSO_client`判定为没有权限时, 则会被导向到`SSO_server`的登录页面 ```` http://SSO_server/login.html?redirect=http://SSO_client/index ```` 使用"导向"而不是"重定向"一词的原因在于**重定向在通常的认知里来说是一个后端操作,在前后端分离的场景下带来了误解** 这个流程中`SSO_server`需要完成以下操作: ````javascript async login(ctx) { const { username, password, redirect } = ctx.request.body...
## 参考 [十分好用的二分查找法模板](https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/) 虽说是模版, 但是如同作者说的一样, **它根本没有必要记忆, 理解之后会认为使用它是理所应当的事情** ## 二分查找: 简单却注重细节 基本思想: **在每一轮循环中排除一半以上的元素, 于是在对数级别的时间复杂度内, 就可以把区间缩小到只剩一个数, 而这个数是不是我们要找的, 单独判断一次即可** 代码示例均采用golang ### 1. 取中位数索引的正确方式 常见: ```` mid := (left + right) / 2 ````...
🌲🕳️ 磁盘满了,导致服务挂了,其实也没人知道,毕竟就我一人在用。还有就是已经一个半月没有写文章了,还是要憋一篇出来呗。 还是不要无病呻吟了,我🤮了,告辞
## 参考 [使用 Workbox 构建 PWA](https://codelabs.developers.google.com/codelabs/workbox-lab-cn/index.html?index=..%2F..%2Fgddchina#0) [Workbox 3:Service Worker 可以如此简单](http://taobaofed.org/blog/2018/08/08/workbox3/) ## 1. Workbox: Google 官方的 PWA 框架 本篇介绍的内容主要为如下几个模块 + **预缓存 precaching** (约等于sw-precache) + **路由控制 routing**(约等于sw-toolbox) + **运行时缓存策略 strategies** (约等于sw-toolbox内置的五个handler) 所有模块如下图...
## 参考 [Service Worker最佳实践](https://x5.tencent.com/tbs/guide/serviceworker.html) [借助Service Worker和cacheStorage缓存及离线开发](https://www.zhangxinxu.com/wordpress/2017/07/service-worker-cachestorage-offline-develop/) [如何优雅的为 PWA 注册 Service Worker](https://juejin.im/entry/597b49915188253e2d60936a) [LAVAS pwa文档](https://lavas.baidu.com/pwa) [Service Worker 全面进阶](https://juejin.im/post/591028fc2f301e006c291c4b) ## 1. 使用前提条件 + **受信域名**: https协议 or `localhost` or `127.0.0.1` + **依赖Promise** + **依赖HTML5...
## 参考 [justjavac-IntersectionObserver](https://github.com/justjavac/the-front-end-knowledge-you-may-not-know/issues/10) [使用Intersection Observer API构建无限滚动组件](https://www.w3cplus.com/vue/build-an-infinite-scroll-component-using-intersection-observer-api.html) [IntersectionObserver API 使用教程](http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html) [polyfill](https://github.com/w3c/IntersectionObserver/tree/master/polyfill) ## 1.介绍 网页开发时,常常需要**了解某个元素是否进入了"视口"**,即用户能不能看到它 传统的实现方式: 监听`scroll`事件后,取得目标元素相对于视口左上角的坐标,由此来判断是否在视口之内,缺点如下: + scroll事件密集,不进行防抖/节流处理的话,容易造成性能问题 + 代码不整洁 使用`IntersectionObserver API`,可以自动**观察元素是否可以见**,这里可见的本质是: **目标元素与视口产生一个交叉区域**,所以这个api叫做"交叉观察器" 也是有点年头了  虽然即便都8102年了, 因为他的兼容性问题, 使用的还不多,不过这些问题应该交给polyfill来解决~  ## 2.使用...
## Sentry Intro 支持范围:**可以理解为支持所有主流语言和框架的接入,没有什么不能接入**  特点: + 只收集错误信息,避免从一堆无用日志中找问题 + 对于前端来说能收集的错误范围: + 自动捕获异常:代码运行时错误 + 主动捕获异常: 接口错误 / 异步操作错误 + 手动抛出异常:) ## Sentry前端使用效果 使用Sentry,避免前端代码在0监控的情况下裸奔:),从目前接入后的最终效果来看,有如下的作用: 1. **【局部】** 能够收集到`JavaScript`代码中的缺陷, 例如常见错误`cannot read property of undefined`,...
## 1. Go - sort模块源码分析 浏览[sort模块源码](https://golang.org/src/sort/sort.go),源码可以整理成如下结构    上面三张图已经能明确的体现出:**`sort`模块到底有什么?内部是什么样的调用流程?自定义类型排序应该如何实现?** ## 2. 整体结构 ### 2.1 如何实现自定义类型的排序? > 一个满足`sort.Interface`接口的类型可以被本包的函数进行排序,方法要求集合中的函数可以被整数索引 ````golang type Interface interface { // Len方法返回集合中的元素个数 Len() int //...
## 回溯算法 解决一个回溯问题,实际上就是一个决策树的遍历过程,只需要思考三个问题: + 路径:已经作出的选择 + 选择列表:当前可以做的选择 + 结束条件:到达决策树底层,无法再做选择 回溯算法的框架 ````golang func backTrack(路径,选择列表) { if 满足结束条件 { result = append(result, 路径) return } for _, 选择 := range 选择列表 {...
## 1. Go中的原子操作 原子性:**一个或多个操作在CPU的执行过程中不被中断的特性,称为原子性。这些操作对外表现成一个不可分割的整体,他们要么都执行,要么都不执行,外界不会看到他们只执行到一半的状态。** 原子操作:**进行过程中不能被中断的操作,原子操作由底层硬件支持,而锁则是由操作系统提供的API实现,若实现相同的功能,前者通常会更有效率** 最小案例: ````go package main import ( "sync" "fmt" ) var count int func add(wg *sync.WaitGroup) { defer wg.Done() count++ } func main() { wg :=...