Decorative image frame

$set采坑记

  前几天做后台管理系统时,里面有一个涉及到对申请者的信息修改,对原来已经有的申请者,只能进行积分的修改或者是删除申请者,同时对新增申请者可以选择姓名、调整积分。由于新增申请者跟原有申请者的操作跟展示效果都不一样,所以在展示申请者的时候,我用tag这个字段来进行区分,最后把这个tag传给后台进行数据处理。新增的obj在推入时就会一并添加一个tag属性,且其值为”add”,删除的是直接使用index对数组中某一项新增tag属性,且其值为delete。展示层对于tag值为delete的则不展示,由于tag这个属性是新增的,所以需要使用$set,否则视图层不会响应。在我添加$set之后,我发现了另外一个诡异的问题,就是在点击删除之后,后面新增的obj都不再展示。此时我打印数据,发现数据是正常的,就是被删除的obj的tag是delete,而之前新增的tag还是add,那为什么会不展示了呢??这个问题我到现在也没搞懂,但是这个问题只有两种可能,一种是我的展示逻辑写的有问题,另一种就是vue有bug。等我去理解$set的源码或许会得到解答。
  最后同事小赵提出了一种解决方案,在获取到申请者数据时,用$set循环为每一个obj添加tag属性,且该值置为空。然后后台有变动的时候,在直接修改tag属性。果然用这种方法之后,视图就正常显示了。但是我还是没搞懂这样子能解决问题的理由。。。等我找到答案时再回来更新,未完待续

用DOMPurify处理传入给v-html内容

  昨天提交代码的时候,同事审核到代码里面用到v-html,要求需对后台传入内容进行转义,否则可能会有安全性问题,比如后台现在传给你的内容是依赖用户输入的,假设后台直接把那段文本传到前端,那么就容易发生xss攻击。假如用户传的是一段scrpit代码,就用可能直接导致网页瘫痪。当时我直接调用了转义函数,结果发现标签被当成文本输出了,所以我知道了所谓转义应该是指的过滤,把非法的输入给过滤。此时DOMPurify就派上用场了。
  DOMPurify使用:一、引入这个库 二、可以直接定义一个全局配置常量 三、调用DOMPurify.sanitize函数对要传入给v-html的内容进行处理。e.g v-html=”DOMPurify.sanitize(itemData.value, DOMPURIFY_CONFIG)”

全局配置参考如下:

DOMPURIFY_CONFIG = {
   USE_PROFILES: {html: true}, //允许所有安全的HTML元素,但不允许SVG或MathML
   ALLOWED_ATTR: [‘style’], //允许html元素上的style属性
   WHOLE_DOCUMENT: true //返回整个文档,包括标签,为false则只返回body内(不包括body)的内容,设置为true是t为了拿到
   style标签
};

fix error——error(loading chunk xx failed.)

  今天在项目中添加登陆功能之后,我发现第一次点击切换路由时是正常的,之后再切换时就会报错(loading chunk xx failed)一番搜索之后找到原因出在vue.config.js中的BASE_URL配置,当其在development时配置的是’./‘,去vue-cli官网看了下原来在history路由模式下,BASE_URL是不能采用相对路径的形式进行配置的。

通过小明的故事认识session

  今天趁着坐地铁的时间阅读了一篇文章,关于理解session的,个人觉得讲的还不错,于是进行一个小结。文章通过故事的形式阐述了session的概念,同时讲到一些客户端与服务端通信时有关安全方面的问题。
  这个故事讲述了一个没有记忆力的小明开了杂货铺,通过用笔记本电脑记录用户信息的故事。安全相关——其中一种方式是笔记本电脑记录的信息就相当于session,每次用户来的时候通过提供小明随机提供的sessionID,小明通过该id在笔记本中找到顾客消费的信息,从而更好的服务客户。另外一种方式是小明通过解密加密过的cookie直接得到客户信息,但是这种方式会使得客户保存过长的cookie,不是非常好。

路由控制权限遇到的加载顺序的问题

  由于那个项目区分了两种用户权限,所以需要对特定用户屏蔽某个路由,防止其通过访问这个路由而看到无关的内容。这个路由下展示的内容也不算敏感,所以这次是前端直接做的屏蔽。倘若是比较敏感的内容,肯定得通过接口去控制。一开始我是选择在配置路由表的地方直接判断用户的身份,从而决定是否推入对应的路由映射。一开始测试感觉是没问题的,就是在本地切换假数据也是可以正常根据用户权限进行展示的。但是当我在本页面进行刷新时,问题出现了——就算有权限的用户也看不到页面,而只能从外面重新进入这个页面。

  找到产生bug的原因是——没有理清代码的加载顺序,其实之前也有其它的bug是因为这个问题造成。这种bug并不都那么容易发现的,尤其当用到该字段的地方不是首页时。因为其它页面被访问时,获取该字段的代码一般都是已执行完毕。所以当你使用一个全局可能都会用到的变量时,尽量要清楚代码执行的顺序或者用到的地方是否响应式的(window.location赋值的变量不是响应式的,可以考虑有vue2.6发布的Vue.observer来代替。如果能保证请求是同步请求的才去选择这种方式对全局变量进行赋值,就算是赋值给store.state也要注意调用的地方,如果是在某个方法里调用时,则要考虑监听这个字段的方式;如果是在template中调用时则不必监听)。

  说回路由的问题,因为如果是从外面直接进来的话,可以直接访问store里存放的用户权限的数据,但是如果是在当前页面直接刷新,此时由于访问用户信息的接口调用比路由表要慢,所以尽管后面接口返回了信息,那页不会再改变对应的路由展示。

  一开始我想着在当前页去进行用户信息的监听,如果是没有权限的用户,则当它访问当前页时,在自动跳转回首页,这样子做其实是问题的,但是如果考虑到之后的扩展性,就是如果这种操作是针对很多页面都需要控制的,那么久需要在各个页面去进行这种判断。后面决定统一放在ROUTER.beforeEach里面进行处理,处理这个东西的过程我主要花了比较多的时间在重构获取用户信息的方式。

  一开始获取用户信息是放在某个页面里面去做的,后面改成在store里面的action,保持了整个文件的一致性。同时,这个请求应该是同步的(同步会对后面的加载造成阻塞,所以这个我觉得还得再考虑),这样子可以确认之后的事情是在获取了用户信息之后再进行的操作。

  另外一个需要注意的是,beforeEach这个钩子在路由每次改变的时候都会重新加载,因此不能在里面做比较消耗性能的事情,然后注意判断,只有在加载到对应路由的时候,才去做对应的事情,而不是每次切换路由都做一些当前路由下不需要做的事情。

同个项目合入两套代码(LSS&&VMS)

  (1)先要明确公共模块,在涉及到公共部分的时候,要先确认下需求,即确认另外的项目是否也需要同样的变动,如果不需要,则需要做兼容处理;
  (2)然后确认下迭代的顺序跟时间(后面迭代的分支在转测前需要把另一个代码分支合入,在合入代码有冲突时,最好是两个项目的人同时决定留下的内容),如果出现合入代码时不明确迭代发布顺序的情况,那么极有可能发生改动内容丢失的情况。

  举个例子在LSS迭代四跟vms1.0.1的开发过程中,我负责LSS而小卓负责vms,由于我们两个没有对齐迭代的发布时间,导致他误认为LSS迭代四的发布时间比vms1.0.1的发布时间要早,所以他在vms1.0.1转测之前合入了迭代四的内容。

  但是在得知了迭代四原来是比1.0.1晚发布的(此时迭代四的分支还没转测,尚存在一些bug),他进行了代码的回滚,但是这次代码回滚对后面我迭代四转测前合入vms分支时造成了影响,也就是我迭代四里面有些修改由于合入了vms1.0.1而丢失了,这是因为vms在进行代码回滚的时候进行了某些删除操作,而合并分支时选择了以vms分支的操作为准而导致的。所以如果一旦合错分支时,再次进行合入要小心比对之前回滚的代码。

  由于这次回滚是在git上直接点击还原的,相当于通过新的合并请求来还原(新的合并请求就相当于这次请求的内容都进行了更改),并不是真正意义上的还原,所以下次合入该分支时,会认为这次还原之后的分支的修改时间是比较靠后的,也就是会以此次还原的代码为准,如果这次还原是通过还原主分支,则不会发生这种事情。

  所以:如果代码合入了主分支之后,主分支后面又没有其他的合入时,要进行回滚可以考虑直接回滚主分支,回滚主分支的风险比较大。。特别是后面有新的合入。所以最好是合入其他迭代的分支之前先考虑好。

登录问题排查

登录失败问题原因:
前端和后端联调时,后台加了一个http配置参数,导致前端cookie校验错误;

登录问题:登录时遇到接口返回“the csrf session token is missing”;

  在后端同事一直没有定位到问题所在时,我自己尝试帮忙排查问题。一开始看到session token is missing的时候,我是觉得可能前端请求接口的时候参数有问题,但是后面发现整个请求过程跟以往并无异样。

  后端同事比对了能在开发环境正常登陆的请求以及我本地登陆异常的接口,发现我本地登陆的时候少了一个session,此时项目经理还认为是Nginx配置的问题。

  我忽然想起来之前工作的公司在遇到这种登陆接口挂掉的时候是通过复制能正常访问网站的cookie到本地开发环境进行登陆的,当我采取同样的方式时发现本地的浏览器的session确实比能正常登陆的少了一条,而复制了session之后也可以正常登陆。通过反馈这一现象,帮助后端同事更快地定位到错误。

季度下拉框代码优化

  结论:对比以上两种,最大的不同其实是思考逻辑。在思考这个内容的起初,我就给自己限定了思考的范围,就是我是从固定数量的季度数开始思考,然后就发现季度是要减去固定的数量才得出的,以致于写出冗长的代码。慢吃是一开始就认定这种是可以做成配置项的,所以思考的入口就很不一样,后面产出的东西就不一样。

在做这种通用性比较强的内容,一定要一开始就往可配置的方向去思考,否则可能就是做很多无用功,走很多的弯路。

优化之后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
getCurrentQuarter () {                                  //计算当前在哪个季度 
const MONTH = new Date().getMonth() + 1, //用getMonth获取的月份比实际月份少一个月
CURRENTQUARTER = QUARTERS_OBJ[MONTH];

return CURRENTQUARTER;

},

/**
* 将某个年份的指定季度推进指定数组里,如果order是true,则是取的指定年份的靠前的年份,反之是取的是靠后的年份
* @param {String} current //年份跟季度的组合 形如2019-02
* @param {Number} beforeNum //需要显示的季度数,不包括当前季度
* @return {Array}
*/
getBeforeCurrentQuarter (current, beforeNum) {
let season = ['1', '2', '3', '4'],
len = season.length,
[year, quarter] = current.split('-'),
index = season.findIndex((item) => item === quarter),
arr = [],
loopIndex = index - 1;

for (let i = 0; i < beforeNum; i++) {

if (loopIndex < 0) {
year--;
loopIndex = len - 1;
}

arr.push(this.handleYearAndQuarter(year, season[loopIndex]));
loopIndex--;
}

return arr;
}

hexo 采坑记

查看了网上的教程,发现有些是部署到自己服务器的,有些是从安装git开始的,总是感觉不太适合自己,所以决定记录一个简历版本的hexo+githubpage的配合记录。

首先,你要在github上配置一个仓库,仓库名字也有讲究,比如我的GitHub名为thinkingOfBetty,所以我的仓库名字就是thinkingOfBetty.github.io。

然后按照下面的步骤进行操作:
(1)全局安装hexo npm install -g hexo
(2) 在空白文件下执行 hexo init
(3) hexo g (生成) hexo s(启动服务) 执行上面两个步骤之后访问localhost:4000端口可以访问到界面
(4)如果你想修改主题,可以访问hexo主题网站上对应的git地址,然后进行下载$类似的命令:git clone https://github.com/litten/hexo-theme-yilia.git themes/yilia(下载好之后配置最外层的_config.yml中的theme)
(5)开始写文章:source中进行编写
(6)上传时要特别注意:master分支上只需要上传public中的内容,之后每次更新文件的时候只需要上传修改的对应静态文件。hexo分支上传的是环境文件。两个分支上都可以配置对应的.gitIgnore文件
(7)下次再新的pc上进行开发时,可以先拉去master的内容,然后通过git checkout 本地分支名 origin/远程分支名
(8)在hexo分支上写文章,然后git add .;git commit -m xx;git push xx; hexo g -d ;之后复制对应的变更给到master中进行上传,此时即可看到界面发生改变。

(9)特别注意的是如果直接从hexo上拉代码之后npm install是不能直接跑项目的,需要在安装对应的theme主题包,因为对应的主题包push不上去,安装见步骤4,安装之后再hexo s即可在本地启动