kruz

kruz 查看完整档案

上海编辑武汉纺织大学  |  软件工程 编辑  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

kruz 收藏了文章 · 2020-03-19

预测最近面试会考 Cookie 的 SameSite 属性

前言

2 月份发布的 Chrome 80 版本中默认屏蔽了第三方的 Cookie,在灰度期间,就导致了阿里系的很多应用都产生了问题,为此还专门成立了小组,推动各 BU 进行改造,目前阿里系基本已经改造完成。所有的前端团队估计都收到过通知,也着实加深了一把大家对于 Cookie 的理解,所以很可能就此出个面试题,而即便不是面试题,当问到 HTTP 相关内容的时候,不妨也扯到这件事情来,一能表明你对前端时事的跟进,二还能借此引申到前端安全方面的内容,为你的面试加分。

所以本文就给大家介绍一下浏览器的 Cookie 以及这个"火热"的 SameSite 属性。

HTTP

一般我们都会说 “HTTP 是一个无状态的协议”,不过要注意这里的 HTTP 其实是指 HTTP 1.x,而所谓无状态协议,简单的理解就是即使同一个客户端连续两次发送请求给服务器,服务器也识别不出这是同一个客户端发送的请求,这导致的问题就比如你加了一个商品到购物车中,但因为识别不出是同一个客户端,你刷新下页面就没有了……

Cookie

为了解决 HTTP 无状态导致的问题,后来出现了 Cookie。不过这样说可能会让你产生一些误解,首先无状态并不是不好,有优点,但也会导致一些问题。而 Cookie 的存在也不是为了解决通讯协议无状态的问题,只是为了解决客户端与服务端会话状态的问题,这个状态是指后端服务的状态而非通讯协议的状态。

Cookie 介绍

那我们来看下 Cookie,引用下维基百科:

Cookie(复数形态Cookies),类型为「小型文本文件」,指某些网站为了辨别用户身份而储存在用户本地终端上的数据。

作为一段一般不超过 4KB 的小型文本数据,它由一个名称(Name)、一个值(Value)和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成,这些涉及的属性我们会在后面会介绍。

Cookie 的查看

我们可以在浏览器的开发者工具中查看到当前页面的 Cookie:

尽管我们在浏览器里查看到了 Cookie,这并不意味着 Cookie 文件只是存放在浏览器里的。实际上,Cookies 相关的内容还可以存在本地文件里,就比如说 Mac 下的 Chrome,存放目录就是~/Library/Application Support/Google/Chrome/Default,里面会有一个名为 Cookies 的数据库文件,你可以使用 sqlite 软件打开它:

存放在本地的好处就在于即使你关闭了浏览器,Cookie 依然可以生效。

Cookie 的设置

那 Cookie 是怎么设置的呢?简单来说就是

  1. 客户端发送 HTTP 请求到服务器
  2. 当服务器收到 HTTP 请求时,在响应头里面添加一个 Set-Cookie 字段
  3. 浏览器收到响应后保存下 Cookie
  4. 之后对该服务器每一次请求中都通过 Cookie 字段将 Cookie 信息发送给服务器。

我们以https://main.m.taobao.com/为例来看下这个过程:

我们在请求返回的 Response Headers 可以看到 Set-Cookie 字段:

然后我们查看下 Cookie:

我们刷新一遍页面,再看下这个请求,可以在 Request Headers 看到 cookie 字段:

Cookies 的属性

在下面这张图里我们可以看到 Cookies 相关的一些属性:

这里主要说一些大家可能没有注意的点:

Name/Value

用 JavaScript 操作 Cookie 的时候注意对 Value 进行编码处理。

Expires

Expires 用于设置 Cookie 的过期时间。比如:

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

当 Expires 属性缺省时,表示是会话性 Cookie,像上图 Expires 的值为 Session,表示的就是会话性 Cookie。当为会话性 Cookie 的时候,值保存在客户端内存中,并在用户关闭浏览器时失效。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样。

与会话性 Cookie 相对的是持久性 Cookie,持久性 Cookies 会保存在用户的硬盘中,直至过期或者清除 Cookie。这里值得注意的是,设定的日期和时间只与客户端相关,而不是服务端。

Max-Age

Max-Age 用于设置在 Cookie 失效之前需要经过的秒数。比如:

Set-Cookie: id=a3fWa; Max-Age=604800;

Max-Age 可以为正数、负数、甚至是 0。

如果 max-Age 属性为正数时,浏览器会将其持久化,即写到对应的 Cookie 文件中。

当 max-Age 属性为负数,则表示该 Cookie 只是一个会话性 Cookie。

当 max-Age 为 0 时,则会立即删除这个 Cookie。

假如 Expires 和 Max-Age 都存在,Max-Age 优先级更高。

Domain

Domain 指定了 Cookie 可以送达的主机名。假如没有指定,那么默认值为当前文档访问地址中的主机部分(但是不包含子域名)。

像淘宝首页设置的 Domain 就是 .taobao.com,这样无论是a.taobao.com还是b.taobao.com都可以使用 Cookie。

在这里注意的是,不能跨域设置 Cookie,比如阿里域名下的页面把 Domain 设置成百度是无效的:

Set-Cookie: qwerty=219ffwef9w0f; Domain=baidu.com; Path=/; Expires=Wed, 30 Aug 2020 00:00:00 GMT

Path

Path 指定了一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部。比如设置Path=/docs/docs/Web/下的资源会带 Cookie 首部,/test则不会携带 Cookie 首部。

Domain 和 Path 标识共同定义了 Cookie 的作用域:即 Cookie 应该发送给哪些 URL。

Secure属性

标记为 Secure 的 Cookie 只应通过被HTTPS协议加密过的请求发送给服务端。使用 HTTPS 安全协议,可以保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改。

HTTPOnly

设置 HTTPOnly 属性可以防止客户端脚本通过 document.cookie 等方式访问 Cookie,有助于避免 XSS 攻击。

SameSite

SameSite 是最近非常值得一提的内容,因为 2 月份发布的 Chrome80 版本中默认屏蔽了第三方的 Cookie,这会导致阿里系的很多应用都产生问题,为此还专门成立了问题小组,推动各 BU 进行改造。

作用

我们先来看看这个属性的作用:

SameSite 属性可以让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。

属性值

SameSite 可以有下面三种值:

  1. Strict仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页 URL 与请求目标 URL 完全一致。
  2. Lax允许部分第三方请求携带 Cookie
  3. None无论是否跨站都会发送 Cookie

之前默认是 None 的,Chrome80 后默认是 Lax。

跨域和跨站

首先要理解的一点就是跨站和跨域是不同的。同站(same-site)/跨站(cross-site)」和第一方(first-party)/第三方(third-party)是等价的。但是与浏览器同源策略(SOP)中的「同源(same-origin)/跨域(cross-origin)」是完全不同的概念。

同源策略的同源是指两个 URL 的协议/主机名/端口一致。例如,https://www.taobao.com/pages/...,它的协议是 https,主机名是www.taobao.com,端口是 443。

同源策略作为浏览器的安全基石,其「同源」判断是比较严格的,相对而言,Cookie中的「同站」判断就比较宽松:只要两个 URL 的 eTLD+1 相同即可,不需要考虑协议和端口。其中,eTLD 表示有效顶级域名,注册于 Mozilla 维护的公共后缀列表(Public Suffix List)中,例如,.com、.co.uk、.github.io 等。eTLD+1 则表示,有效顶级域名+二级域名,例如taobao.com等。

举几个例子,www.taobao.comwww.baidu.com是跨站,www.a.taobao.comwww.b.taobao.com是同站,a.github.iob.github.io是跨站(注意是跨站)。

改变

接下来看下从 None 改成 Lax 到底影响了哪些地方的 Cookies 的发送?直接来一个图表:

从上图可以看出,对大部分 web 应用而言,Post 表单,iframe,AJAX,Image 这四种情况从以前的跨站会发送三方 Cookie,变成了不发送。

Post表单:应该的,学 CSRF 总会举表单的例子。

iframe:iframe 嵌入的 web 应用有很多是跨站的,都会受到影响。

AJAX:可能会影响部分前端取值的行为和结果。

Image:图片一般放 CDN,大部分情况不需要 Cookie,故影响有限。但如果引用了需要鉴权的图片,可能会受到影响。

除了这些还有 script 的方式,这种方式也不会发送 Cookie,像淘宝的大部分请求都是 jsonp,如果涉及到跨站也有可能会被影响。

问题

我们再看看会出现什么的问题?举几个例子:

  1. 天猫和飞猪的页面靠请求淘宝域名下的接口获取登录信息,由于 Cookie 丢失,用户无法登录,页面还会误判断成是由于用户开启了浏览器的“禁止第三方 Cookie”功能导致而给与错误的提示
  2. 淘宝部分页面内嵌支付宝确认付款和确认收货页面、天猫内嵌淘宝的登录页面等,由于 Cookie 失效,付款、登录等操作都会失败
  3. 阿里妈妈在各大网站比如今日头条,网易,微博等投放的广告,也是用 iframe 嵌入的,没有了 Cookie,就不能准确的进行推荐
  4. 一些埋点系统会把用户 id 信息埋到 Cookie 中,用于日志上报,这种系统一般走的都是单独的域名,与业务域名分开,所以也会受到影响。
  5. 一些用于防止恶意请求的系统,对判断为恶意请求的访问会弹出验证码让用户进行安全验证,通过安全验证后会在请求所在域种一个Cookie,请求中带上这个Cookie之后,短时间内不再弹安全验证码。在Chrome80以上如果因为Samesite的原因请求没办法带上这个Cookie,则会出现一直弹出验证码进行安全验证。
  6. 天猫商家后台请求了跨域的接口,因为没有 Cookie,接口不会返回数据
  7. ……

如果不解决,影响的系统其实还是很多的……

解决

解决方案就是设置 SameSite 为 none。

以 Adobe 网站为例:https://www.adobe.com/sea/,查看请求可以看到:

不过也会有两点要注意的地方:

  1. HTTP 接口不支持 SameSite=none

如果你想加 SameSite=none 属性,那么该 Cookie 就必须同时加上 Secure 属性,表示只有在 HTTPS 协议下该 Cookie 才会被发送。

  1. 需要 UA 检测,部分浏览器不能加 SameSite=none

IOS 12 的 Safari 以及老版本的一些 Chrome 会把 SameSite=none 识别成 SameSite=Strict,所以服务端必须在下发 Set-Cookie 响应头时进行 User-Agent 检测,对这些浏览器不下发 SameSite=none 属性

Cookie 的作用

Cookie 主要用于以下三个方面:

  1. 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  2. 个性化设置(如用户自定义设置、主题等)
  3. 浏览器行为跟踪(如跟踪分析用户行为等)

Cookie 的缺点

如果被问到话,可以从大小、安全、增加请求大小等方面回答。

参考

  1. MDN
  2. HTTP是一个无状态的协议。这句话里的无状态是什么意思? - 灵剑的回答 - 知乎
  3. Chrome 80.0中将SameSite的默认值设为Lax,对现有的Cookie使用有什么影响? - 紫云飞的回答 - 知乎
  4. 一些内部文章

各种系列

各种系列文章目录地址:https://github.com/mqyqingfeng/Blog

如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者 有所启发,欢迎 star,对作者也是一种鼓励。

再其他

建立了一个「前端校招面试冲刺互助群」,欢迎加「taoxiaozhao233」 入群~

查看原文

kruz 赞了文章 · 2020-03-14

【整理】前端优化得有个好手段,比如看这个清单🍑🍒🍓🍆🌽

前端优化指南

一名合格的Web前端工程师,Web前端性能优化是一个必须要掌握的知识。 大部分都是规规矩矩写好代码,设计模式好并项目好管理。
而且在HTTP请求和代码耗时间的地方着手。

  • 页面级别的优化,比如减少 Http 请求次数、加快资源的加载速度;
  • 代码级别的优化,页面重新渲染一次会经过浏览器的重排(reflow)和重绘(repaint),这两部操作是非常耗时的

而网页性能优化,缓存优化、加载时优化、动画优化呢?
所以我们才对浏览器下手,了解它的缓存机制。

可参考的书籍📚:★《高性能网站建设指南》★《HTTP权威指南》★《Web性能实践日志》★《你不知道的JavaScript》★《方寸有度:百度移动用户体验设计之道》★《全栈应用开发:精益实践》★《渐进增强:跨平台用户体验设计》★《前端工程化:体系设计与实践》★《前端进阶之路:前端架构设计》★《高效前端:Web高效编程与优化实践》★《NODEJS硬实战笔记》
甚至☆《学会提问》☆《刻意练习》☆《代码整洁之道》
❤`•.¸¸.•´。◕‿◕。。◕‿◕。
看看哪些适合你,又有哪些可以参考的。

吾观自古贤达人,功成不退皆殒身

东风不与周郎便,铜雀春深锁二乔

我寄愁心与明月,随风直到夜郎西

故人西辞黄鹤楼,烟花三月下扬州

金樽清酒斗十千,玉盘珍羞直万钱

参考

想了解更多,点击【🎯Find the latest breaking √vue3 & vue-cli 3+ News.

。◕‿◕。Cool Friends。◕‿◕。
Thanks♪(・ω・)ノ

image.png

查看原文

赞 107 收藏 83 评论 1

kruz 关注了专栏 · 2020-03-05

一个前端菜鸟的成长史

前端知识积累

关注 96

kruz 赞了文章 · 2020-03-05

人人都能懂的Vue源码系列—01—Vue源码目录结构

阅读Vue的源码,或者说阅读一个框架的源码,了解它的目录结构都是很有帮助的。下面我们来看看Vue源码的目录结构。
vue源码目录结构

Vue各目录简介

下图是Vue各个目录的功能介绍

Vue源码目录结构详细
上图就是关于Vue源码整体目录结构的介绍了,我们熟悉每个模块具体的功能之后,对我们之后继续研究源码是很有帮助的。下次谈论的主题是Vue的构造函数,当new Vue实例的时候,会发生什么呢?生成的Vue实例又有哪些属性和方法呢?我们下篇文章会进行详细的说明。
人人都能懂的Vue源码系列文章将会详细的介绍Vue源码的方方面面。为了让初学者也能读懂,尽量把知识点分割的很小。希望大家耐心等待更新,如果对文章内容有疑问或者质疑,欢迎在评论区进行讨论。

参考资料

  1. Flow类型检查
  2. Typescript类型检查
  3. Snabbdom
  4. Vue-server-renderer
  5. weex-vue-framework
查看原文

赞 43 收藏 46 评论 4

kruz 收藏了文章 · 2020-03-01

阿里等大厂的研发流程,进去前先了解一下

本文 GitHubhttps://github.com/JavaFamily 已收录,有一线大厂面试完整考点和系列文章。

前言

我的读者好像学生居多,然后大家最近问的比较多的一个话题就是大厂的研发流程,都比较好奇,整个流程是怎么操作的。

我也不多BB了,那下面就跟随暖男的脚步,走进大厂研发流程吧。

正文

我们先看看一个产品有哪些研发流程,帅丙就用自己接触的阿里系的研发流程举例了,这也基本上是互联网大厂的研发流程了,可能细节有出入,但是绝对大同小异。

我问了下字节,多多,腾讯的朋友出入不大,所以还是具有代表性。

看完流程我们就一个个点的去看看每个环节干了些啥,我们开发同学在这个环节需要做啥,以及在每个环节的职能。

需求提出:

这个环节主要是产品爸爸给我们提需求,每个需求都是他们从用户,或者自己绞尽脑汁想出来的,但是产品爸爸还拿不准,不能直接敲定,所以就需要我们大家(产品,UI,前端,后端,客户端和测试)一起讨论一下,看看这个需求是否合理,或者这个需求是否有意义,能否达到预期,技术实现的成本,周期等等。

一旦聊成了,他们就会进入下一个阶段,聊不成他会想方设法让你答应,然后进入下个阶段,知道我为啥叫产品爸爸了吧?

需求PRD提出:

这个阶段,产品爸爸会根据第一版聊下来的结果,大致出一个Demo版本的PRD,会画出初版的原型图,并且配上文字说明,所有涉及到的业务,还有交互细节都会罗列出来。

大致就是下图这样:

这个时候大家又会围绕这一版本去开会讨论,敲定细节,这个环节会久点,因为细节比较认真,逻辑也不能出错,还有UI稿子也得敲定,这里如果不敲定逻辑,UI提前去画原型图,后面假如逻辑推翻,一切重来就会浪费大量时间。

这一环节大家都会把细节问清楚,不了解的点也会去了解,测试,开发,UI我们都会在会议上提出自己的观点,自己的意见,然后等产品反馈,最后意见一致之后,产品当天就回改出敲定版本。

UI就会按照产品爸爸的意思去作图,接下来就是交互设计评审了。

交互设计评审:

UI会画出客户端,前端,H5开发所需要的UI图,基本上就是我们看到的产品的样子了,不过还是要敲定细节,比如按钮合理不,或者上面数据是否在这展示,或者这里展示的数据是否合理。

这个环节会比较快,只要UI按照之前敲定的逻辑开发,出入不会很大,一般都是小改。

但是也不乏很多,之前敲定了情况,等UI按照敲定版本出了图,但是却发现出图之后有些不合理的点,比如是否应该在这里展示GMV(销售总额),或者是否这样展示活动规则啥的,会有这种情况,不过是小概率事件,改动也不会特别大。

UI界面:

大家看到的这种操作界面,按钮,图标的各种位置和图案,都是UI在这个阶段设计好的。(我什么都没暗示,不用关注我的B站

大家敲定后就进入我们开发人员的回合了。

概要设计:

概要设计,这个是大厂程序员需求下来之后基本上都会做的一步,不过看需求大小,可能很多小需求直接就详细设计了,也有啥设计都不用做的小改动,具体需求具体分析嘛。

很多不了解的同学可能会问,需要设计什么呢?为什么要设计呢?

问得好,经常看我文章的都知道,技术是把双刃剑,你用了技术之后你是不是需要列出他的优点缺点,出问题之后的解决方案,还有可能出现的问题注意点等等。

这么是为了让你能有把控力,比如你这个需求接入了新技术EsElasticsearch)你什么都不管你就是要接入它,你把他开发好了上线了,但是有啥坑你知道么?上线崩了怎么办?

不主动,不拒绝,不负责,这是渣男的行径,我们需要负起责任。

这个环节你需要考虑这个需求涉及到哪些服务了,需要新增哪些接口,修改哪些接口,表有现场的还是要新建表,字段要新建么?

其实远远不止这些问题,这就是我们做设计的主要原因,也是大家工作里面能成长的途径之一,你以为大佬们的经验是怎么来的?

推荐工具:Xmind/ProcessOn

ProcessOn是我使用最频繁的工具了,我身边也有很多小伙伴在用,也推荐大家都使用:

大家在学习,看书等等的时候做个脑图,后面学习和复习的时候思路会很清晰,而且效率瞬间很多,形成知识体系。

概要设计一般就是做个大概,给大家看一下我自己在设计ES相关的需求的时候的概设,比较粗糙看个大概就好了:

这个设计好了,就需要给Leader看,看理解程度,一两次返工是有可能的,如果你像或者像敖丙一样笨的话,是有可能会被打回N次的,这里我得提一下,好好做设计好处大大的有,自己体会。

然后会进行一轮测试用例评审,比如你涉及哪些服务,新增了哪些接口,改了哪些接口,都是要同步出来的,至于为啥?

是因为测试会依据这个数据,评估影响范围,方便他写测试用例,后面会提到。

详细设计

小伙伴又要问了啥是详细设计呀帅丙

傻瓜,简单呀,见名知意嘛,概要设计是大概的设计,详细设计是详细的设计。

我们研发的时候整个流程往往很复杂,如果你理解不对直接就写代码,最后容易造成返工,延期,加班,被骂,心情差,回家吵架,离家出走,露宿街头,饥寒交迫,被迫吃野味,然后全国。。。。

看到不做详细设计的后果了吧,其实大家花点时间做详细设计很有必要,你思路完全清晰了,写代码那就是分分钟的事情,不是嘛?

那再看看帅丙的一个小设计吧,之前文章中大量的流程图,时序图都来自它,主要是这玩意还是在线的,都不用下载很方便啊。

详细设计的工具我用的就是之前提到的在线作图神器:ProcessOn https://www.processon.com

还是我自己之前设计的一些流程图,大家可以看看:

这个环节一样重要,这个地方如果你能想好很多细节,开发的时候效率会高很多,像我上面的一些点,基本上就是看着图开发了。

这个环节一般上不需要Leader参与,但是如果你有疑问或者不了解的点还是要提出来的。

测试用例评审:

上面我们说过,测试会根据你的概要设计,评估你的影响范围,你的影响点,新增和改动的接口啥的,去编写自己的测试用例。

测试用例,主要是为了把改动点影响点都考虑到,测全一点,免得上线了影响别的现有业务,也是为了把你开发的功能可能出现的bug给排除了。

我拿个小破站的小用例大家看看,这个比较粗糙但是也有点那味了。

这个环节也会开会讨论,也是细节的确定,比如他写的是否合理,或者有什么点没考虑到,大家有没有补充的。

接口定义&开发&前后端联调

这个环节其实比较好理解,啥都敲定了,那就开发呗,开发差不多了,就得前后端联调了。

这里有个小细节还是想说一下,一般开发前我们都会提前定义数据类型,接口名称,然后在公司的接口工具上给出链接和参数,方便前端爸爸mock数据。

他总不能等我们后端开发完了,才去开发嘛,这样效率打折扣,所以都是后端先定义好,然后前后端并行开发的。

后端开发好,一般都是会发布到联调环境,我们有哪些环境,联调环境在我们所有的环境中处于哪个地位呢?

大家可以看到我列出了我们开发的所有环境。

Tip:日常环境不能由开发人员发布,是因为测试流程比较久,所以不能中断,如果你一直发布会影响测试的效率,在发布期间他们是没办法干活的,而且很多部门涉及相同的服务,你发布还会影响别人。

测试发布之前,在测试群里问问可以发某个服务么,大家觉得不影响,那么就可以发了,懂了吧。

预发环境,也叫灰度环境,这是跟线上数据一样的一个环境,只是只能内网访问,一般这一步是防止很多是因为日常的数据量不够真实,数据级别达不到线上的量级无法测出的bug。

扯远了,联调完了就是代码Review了。

代码Review:

codeReview环节,画一下重点,这可能是整个研发流程中,让你成长最快的一个环节,让组员和Leader Review你的代码,往往他们能给你很多业务上和技术上的建议和意见。

过来人的经验你就说香不香吧,以前老大经常没时间,但是我就是烦着他要Review,后来他说不用review了,但是我还是要组员大佬review,因为我很享受别人对我提建议的时候,这不就是成长,扫盲的好时机嘛。

提测&灰度发布&产品第一次验收

这一阶段就是把代码都发到日常环境,然后等测试爸爸测试,这个环节开发同学如果没BUG是比较轻松的,等着就好了,可以看看丙丙的文章啊,看看丙丙的B站视频什么的。

但是如果你BUG多,那我觉得你可能会生不如死,因为有的bug真的找很久很久的,调用链路又长,特别是跨服务又涉及消息队列,或者第三方的接口什么的。

img

img

总之你也不知道会出现什么bug,我看身边的大神也只能用经验避免常见的吭,孰能生巧吧。

发布计划

敲黑板,这个确实是比较重要的环节,这个环节主要是开发同学和前端同学说好一个发布时间,然后制定一个发布计划,为啥要发布计划呢?

我们开发一个需求,可能涉及到N个服务,这些服务是有依赖关系的,那就需要打包,比如订单系统,依赖人员系统。优惠券系统,也依赖人员系统,然后订单系统还依赖优惠券系统,是不是有点乱了?

我们看图:

打包和发布顺序原则上是一样的,从没完全依赖的服务按照顺序发布到最后一个服务。

生成环境上线:

这就是神圣而庄严的上线环节,一般在这个环节丙丙都是要洗手洗澡,然后才点下那个神圣的发布按钮。

一般现在都是自动化发布,界面上点点就好了,记得丙丙大学发布都是进服务器一个个kill进程,替换jar包然后重启。

现在都是分布式的集群,这样发无疑会累死,我之前负责的系统有50多台机器,一般都是4台4台发布。

日志观察&产品第二次验收

一般发布第一批之后不会马上发布第二批,而是观察错误日志,看看是否正常,有时候会发现还是会出现异常情况的,那就保留错误日志,然后回滚。

知道解决了再发布,顺利的话就没啥错误,一口气发完了,看了下时间凌晨了,那发完差不多也得回家了。

一次发布可能涉及服务多的话,真的有可能发布这么久,但是没办法,线上出问题就是掉脑袋的事情。

日志观察一般公司都有错误日志搜集系统,或者自己登录跳板机查看就好了。

没问题,发完之后告诉产品大大就好了。

需求结束

至此基本上一个需求可能就结束了,其实还是很不容易的,短的需求几天,长的需求几个月,中间涂涂改改,BUG,技术难点都是你要面对的,不过没啥大问题,我们技术人嘛皮实能顶。

总结

产品研发流程大家是不是觉得有点复杂,或者觉得很多点有点小题大做了,不瞒你说,刚开始我也这么认为的,但是随着时间的推移,你会发现有时候越是这样规范,越是提升了效率,也提升了产品质量。

对自己设计的严苛也会让你的业务能力提升,开发考虑的点也越来越广泛,我想大佬应该都是这样走过去的,那没啥好说的,我们也走。

最后给大家看看我自己搞的一个项目管理模板吧,基本上能适用大部分项目了,要xmind格式的公众号回复【项目】即可。

我是敖丙,一个在互联网苟且偷生的程序员。

创作不易,不想被白嫖,各位的「三连」就是丙丙创作的最大动力,我们下篇文章见!


本文 GitHubhttps://github.com/JavaFamily 已经收录,有大厂面试完整考点,欢迎Star。

你知道的越多,你不知道的越多

查看原文

kruz 收藏了文章 · 2020-03-01

重新认识caniuse

困惑

相信大家都曾用caniuse网站查询过css、js的一些兼容性问题,并且都从它反馈的兼容性数据中获益,让我们的线上项目更加稳定、和谐的跑在用户电脑里。不过对于caniuse页面上的一些细节,我们可能会感到困惑或者模棱两可,今天就带着大家一起来重新认识caniuse这个网站,并对它的原理和细节做些探究。

1.1从babel-preset-env说起

babel-preset-env是babel6中极力推崇的一个preset,preset代表的是babel plugins的一个集合,相当于一堆plugins的一个统称。在babel最开始打江山的时候,es6标准也发布不久,babelrc的配置中只需要添加es2015这样的preset。但随着es2016、es2017的相继出现,babelrc很快就会变成一堆挂历式的集合体。所以babel给出了env这个杀器,既避免了es20xx的出现,又可以与caniuse的权威数据融合,让配置preseet科学而简单。

{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["last 2 versions", "safari >= 7"]
      }
    }]
  ]
}

这是babel官网给出的env配置方案,"last 2 versions", "safari >= 7",这两个条件是并集的关系,babel将会分别给出满足这两个条件的浏览器及版本,并会进行合并,最后算出一组浏览器及对应最低版本的数据。

babel是用来转换js语法的一个编译器,为什么还能知道满足env条件的浏览器跟版本,这要从browserslist这个库说起.

1.2 Browserslist

这个库不仅仅用在babel-preset-env中,像autoprefixer这样知名的库,也是用到了它。

last 1 version
> 1%
maintained node versions
not dead

browserslist能够把上面近似于人类语言的配置,转换成一组浏览器集合。不过它的主要职责就是转化上面的配置内容,按照正则过滤出正确浏览器列表内容,而它本身不提供浏览器列表的来源。

1.3 caniuse-lite

Browserslist的浏览器数据来源就是这个caniuse-lite,而它是caniuse-db库的精简版本,是从caniuse-db库衍化而来,只不过对caniuse-db数据按照一定规则做了简化,使得库的大小减少了许多,并且提供一些查询api供他人使用,每当caniuse-db更新时,也会跟着一起发布版本。

1.4 caniuse-db

caniuse的npm包,提供了caniuse网站查询所需的所有数据。


2.caniuse库的介绍

caniuse-db的github地址在此,caniuse鼓励大家去github上提交pr,经过审核之后就可以被录用到它的官方数据库中。

2.1如何为caniuse贡献数据

首先,它为我们准备了sample-data.json文件,按照此文件格式把需要增加的特性名称、介绍和浏览器兼容性情况填写清楚,保存并放到features-json文件夹中,最后提交pull request即可,审核完毕后会自动把这部分新增特性保存到data.json中。data.json就是caniuse官方的数据库导出文件,供其他库调用,每次json文件变化后,都会release一个新版本。

2.2 sample-data.json

作为新特性发布的样本文件,内容如下:

{
  "title":"Sample title",
  "description":"Sample description",
  "spec":"http://example.com/path/to/spec.html",
  "status":"wd",
  "links":[
    {
      "url":"http://example.com/path/to/link.html",
      "title":"Link title"
    }
  ],
  "bugs":[
    {
      "description":"Sample bug description"
    }
  ],
  "categories":[
    "CSS"
  ],
  "stats":{
    "ie":{
      ...
      "11":"u"
    },
    "edge":{
      ...
      "18":"u"
    },
    "firefox":{
      ...
      "67":"u"
    },
    "chrome":{
      ...
      "75":"u"
    },
    "safari":{
      ...
      "TP":"u"
    },
    "opera":{
      ...
      "58":"u"
    },
    "ios_saf":{
      ...
      "12.2":"u"
    },
    "op_mini":{
      "all":"u"
    },
    "android":{
      ...
      "67":"u"
    },
    "bb":{
      "7":"u",
      "10":"u"
    },
    "op_mob":{
      ...
      "46":"u"
    },
    "and_chr":{
      "71":"u"
    },
    "and_ff":{
      "64":"u"
    },
    "ie_mob":{
      ...
      "11":"u"
    },
    "and_uc":{
      "11.8":"u"
    },
    "samsung":{
      ...
      "8.2":"u"
    },
    "and_qq":{
      "1.2":"u"
    },
    "baidu":{
      "7.12":"u"
    }
  },
  "notes":"Sample notes for feature, explain partial support here",
  "notes_by_num":{
    "1":"First note..."
  },
  "usage_perc_y":0,
  "usage_perc_a":0,
  "ucprefix":false,
  "parent":"parentfeatureid",
  "keywords":"example,keywords",
  "shown":false,
  "ie_id":"",
  "chrome_id":"",
  "firefox_id":"",
  "webkit_id":""
}

简要介绍下其中的几个关键字段:

(1)title:特性名称
(2)description:特性介绍(搜索时的关键字)
(3)spec:跳转到详细介绍页面
(4)links:拓展内容介绍
(5)keywords:搜索时的关键字
(6)status:特性在标准中的状态

  • ls - 标准
  • rec - W3C 推荐
  • pr - W3C 建议
  • cr - W3C 候选
  • wd - W3C 手稿
  • other - 非W3C, 但流行的
  • unoff - 非官方

(7)categories:分类

  • HTML5
  • CSS
  • CSS2
  • CSS3
  • SVG
  • PNG
  • JS API
  • Canvas
  • DOM
  • Other
  • JS
  • Security

从上面分类可以看出,caniuse并不只是一个查询css兼容性的网站。

如果想查看目前caniuse已经支持了多少种特性,以及特性对应的分组信息,可以点击这个网址

(8)stats:浏览器对特性的支持情况

  • y - (Y)es, supported by default 完全支持
  • a - (A)lmost supported (aka Partial support) 部分支持
  • n - (N)o support, or disabled by default 不支持
  • p - No support, but has (P)olyfill 不支持,但有替代方案
  • u - Support (u)nknown 未知
  • x - Requires prefi(x) to work 需要加前缀
  • d - (D)isabled by default (need to enable flag or something)需要打flag
  • '#n' - Where n is a number, starting with 1, corresponds to the notes_by_num note. 支持,请看介绍第n条

(9)stats:浏览器列表

  • ie
  • edge
  • firefox
  • chrome
  • safari
  • opera
  • ios_saf
  • op_mini
  • android
  • bb
  • op_mob
  • and_chr
  • and_ff
  • ie_mob
  • and_uc
  • samsung
  • and_qq
  • baidu

以上浏览器列表是固定的,用户不能增加和缺少某个浏览器类型。

总结

每当增加一个新特性时,都要对以上浏览器列表以及对应版本列表进行实测,特性的测试可使用以下两个官方推荐的网站https://www.browserstack.comhttp://saucelabs.com
对于第二个网站,可用于因浏览器兼容性造成生产事故的还原测试,在其网站的虚拟机内完成特定浏览器特定版本的实测,在测试完成后可以观看操作视频,并支持导出功能,这对技术解决兼容性问题,提供了第一现场的操作流程,方便问题的解决。

3.caniuse网站介绍

3.1主页面介绍

clipboard.png
页面红字标注了4个地方
(1)代表了这个介绍框的内容隶属于一个特性,也就是我们在features-json看到的一个个跟特性相关的文件,没有#标志的不属于特性。
(2)代表这个特性在标准中所处的一个状态,具体参照前文对sample-data.json的介绍
(3)对于这个特性,在全球、中国所有浏览器中,分别有多少完全支持和部分支持,把两部分值加起来,得到总份额。
(4)浏览器基线,代表对应浏览器current状态的版本号。基线往上是该浏览器的低版本,并对相同支持情况的版本进行合并。基线往下是未来的三个版本,并进行状态合并。

3.2浏览器信息统计

caniuse关于浏览器的数据,主要都来源于statcounter,此网站统计了全球以及各国的浏览器使用情况。

上面提到的浏览器基线及版本号列表,都是基于statcounter上个月份的数据统计。
例如chrome v73在3月12号发布了版本,但在caniuse网站里,v72还是作为了current版本,就是因为caniuse的分析数据来源于2月份的统计数据,数据并不是实时更新。

3.3详情

clipboard.png
页面红字标注了4个地方
(1)浏览器对特性支持情况相同的版本区间
(2)对特性的支持情况
(3)火狐40-火狐64的发布时间
(4)火狐40-火狐64,在全球、中国的使用份额

4.想法

知道了caniuse的数据来源及原理之后,我们是否可以打造属于自己公司的caniuse,暂且就叫做caniuse-shein

(1)
目前,我司的前端只负责中后台系统,面向的用户群体有限。
而我手头上有一个专门为公司前端而打造的APM项目,里面包含了详尽的浏览器版本及份额数据,将APM项目中的浏览器数据与caniuse的特性数据相结合,可以制作出类似于caniuse官网的特性查询分析页面,但报表数据只关心我司的用户群里使用的浏览器,而非依据全球或者全国。

(2)
babel-preset-env这个插件也可以结合caniuse-shein的数据,给出对应浏览器份额的babel插件列表

招聘

  1. 有想找工作的前端朋友,可以投递【字节跳动】,base全国,目前海量HC,从速投递。请扫描下图获取所有岗位列表

image

2.另外有想了解招聘详情的同学也可加我微信 stoneyAllen

查看原文

kruz 赞了回答 · 2020-02-23

解决如何在ie11里使用a连接创建动态下载文件流?

查了资料,可以使用微软独家的msSaveBlob, 这个方法支持ie10及以上。

var downloadFileName = self.formatTimestamp()+ '-' + self.logFilename;

        if(window.navigator.msSaveBlob){
            // for ie 10 and later
            try{
                var blobObject = new Blob([self.output]); 
                window.navigator.msSaveBlob(blobObject, downloadFileName); 
            }
            catch(e){
                console.log(e);
            }
        }
        else{
            var file = "data:text/plain;charset=utf-8,";
            var logFile = self.output;
            var encoded = encodeURIComponent(logFile);
            file += encoded;
            var a = document.createElement('a');
            a.href = file;
            a.target   = '_blank';
            a.download = downloadFileName;
            document.body.appendChild(a);
            a.click();
            a.remove();
        }

关注 2 回答 1

kruz 赞了问题 · 2020-02-23

解决如何在ie11里使用a连接创建动态下载文件流?

下面的函数,在其他浏览器里可以下载一个txt文件,但是在ie11里跳转到一个空白页面。文件被url编码后放在了地址栏。没有触发下载。请问怎么才能在ie11里也触发下载文件?

完整项目地址:https://github.com/wangduandu...

    this.downloadLog = function() {
        var file = "data:text/plain;charset=utf-8,";
        var logFile = self.getLog();
        var encoded = encodeURIComponent(logFile);
        file += encoded;
        var a = document.createElement('a');
        a.href = file;
        a.target   = '_blank';
        a.download = self.formatTimestamp()+ '-' + self.logFilename;
        document.body.appendChild(a);
        a.click();
        a.remove();
    };

图片描述图片描述

关注 2 回答 1

kruz 回答了问题 · 2019-12-26

每次 npm install package-lock.json会改变

npm的安装原理:
微信图片_20191226132938.png

如果你的package.json和你的package-lock.json没有冲突的话,不会更新package-lock.json文件,反之会更新。

测试npm版本: 6.13.1

为什么会冲突?比如你手动改了版本号,比如依赖了core-js 3.4.5,如图

## package.json
"dependencies": {  
  "core-js": "~3.4.5"  
}
## package-lock.json
"dependencies": {  
  "core-js": {  
    "version": "3.4.7",  
    "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.4.7.tgz",  
    "integrity": "sha1-PdplYR2VaZtet3QupFHqBS03qmU="  
  }  
}

依赖的是core-js ~3.4.5, 锁定的是3.4.7
你把package.jsoncore-js 的依赖改成 ~3.4.6 , ~3.4.7,重新安装都不会使 package-lock.json变化, 因为lock文件里面保存的版本比package文件里面的大。

但是如果你把package.json文件里面的版本直接改成 "core-js": "~3.4.8", 这就比lock文件里面的版本要高了,需要重新下载最新的,会下载符合3.5.x 的最新版。同时更新lock文件。

关注 7 回答 4

kruz 提出了问题 · 2019-02-20

java web项目前端部分如何做优化?

问题描述

公司有项目是基于srpingmvc + jsp做的,前端展示页面就是页面引入js,css等,由于历史原因,并没有做前端工程化, 而且项目不适合做成完全前后端分离的,我现在想做一些脚手架的东西,比如给上线的js加hash码,图片提取后放到CDN,替换html文本,还有就是压缩合并js这些。有没有一种解决方案来做这个脚手架的框架或者思路,希望各位有经验的给点意见。

关注 3 回答 2

认证与成就

  • 获得 0 次点赞
  • 获得 2 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 2 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-05-12
个人主页被 218 人浏览