分类
技术 招聘

代友招聘:珠海/远程 APISIX 前端

另外我们 OpenResty Inc. 也在持续招聘后端工程师/系统工程师,可选北京、深圳,也支持远程,详情请点击:OpenResty Inc. 招聘后端工程师


支流科技(APISIX)是一家开源基础软件创业公司,围绕着 Apache APISIX 构建下一代微服务,用户包括:中航信、海尔优家、腾讯云、空中云汇、NASA、欧盟数字工厂等 100 多家国内外知名公司和科研机构。

招聘中高级前端工程师,主要负责:

  1. 企业官网开发
  2. Dashboard 型产品开发

主要待遇:

  1. 全职工作,有五险一金
  2. 珠海上班最好,远程亦可
  3. 有(丰厚)期权

需要:

  1. 独立工作能力
  2. 掌握 Web 前端技术
  3. 掌握前端工具链
  4. 熟悉软件工程体系
  5. 至少熟练使用一个前端框架

加分项:

  1. 有开源项目参与经验
  2. 有长期博客
  3. 有远程工作经验
分类
技术 招聘

代友招聘:广州垂直领域知识付费

公司从 2018 年开始做相关的产品研发,到现在已经经历了两轮迭代,目前正在招聘新鲜血液,准备在 2020 年再搏一搏。

招聘链接在这里,长期招聘:https://www.zhipin.com/job_detail/?query=硅碳鼠&city=101280100&industry=&position=,目前主要招聘中级以上的前端和 PHP。

感兴趣的同学可以直接联系,或者找我推荐。

分类
js 技术

使用 JS 模拟元素被 click

需求来自于我厂的 QA 产品。在这个产品中,我需要在浏览器插件里模拟用的各种行为,比如:点击。

click 事件前后发生了什么

最初我觉得点击嘛,能有啥问题,就直接广播 click 事件呗。结果发现并非如此。实际上,一次 click 背后,其实有一大套的逻辑:

  1. 移动到按钮上时,会依次触发 mouseovermouseenter 事件,前者冒泡,后者不冒泡
  2. 鼠标按下时,广播 mousedown 事件
  3. 如果此时其它元素有焦点,那么该元素会先失去焦点,并广播 blur 事件
  4. (下一节补充)
  5. 按钮获得焦点,广播 focus 事件
  6. 如果因此影响到 DOM,那么会等待 DOM 变更
  7. 如果鼠标没有离开按钮,按钮广播 mouseup 事件
  8. 最后广播 click 事件
  9. 在移动设备上,可能会有 300ms 延迟

其实(5)并不准确,每一次事件广播都是独立的 event loop ,所以上面每一步都可能产生 DOM 变化和其它次生变化,也可能导致一些操作或功能不符合预期。比如:

  1. 一个搜索框。输入后自动搜索,结果以 dropdown 形式展示在下面
  2. 点击 dropdown 里的条目可以跳转
  3. 搜索框 blur 时 dropdown 移除

此时,dropdown 里的条目可能无法点击。因为点击时,输入框先 blur,之后 dropdown 隐藏,接下来 mouseup 事件触发在别的元素上,于是不会有 click 事件。

最简单的解决方案,给 blur 事件加延迟,10ms 就够。

(关于上面的事件触发顺序,可以用这个的 codepen 尝试)

click 事件对 change 事件的影响

接下来,回到 QA 产品。

我真正踩的坑,是 change 事件没有按照预期触发。大家知道,Vue 组件通过 $emit('input') 可以更新绑定在 v-model 里的值。触发的时机一般通过侦听 DOM input 或者 change 来决定。如果 change 无法正确触发,那么 QA 产品自然而然就无法正常工作。

实际上,在上一节的 click 逻辑中,第(4)步可以展开为:

如果失去焦点的元素是 <input> 或者 <textarea>,则该元素会广播 change 事件。

模拟 click 动作的代码

最后,演示一下最终代码:

const options = {
  bubbles: true,
  cancelable: true,
  view: window,
};
let event = new MouseEvent('mousedown', options);
elem.dispatchEvent(event);
elem.focus();
event = new MouseEvent('mouseup', options);
elem.dispatchEvent(event);
elem.click();

相关链接

分类
服务器端

树莓派4 安装 OpenResty + PostgreSQL

为了给 OpenResty.org 添加论坛链接,在本地搭建开发环境,选择用树莓派搞。记录一下,以备将来回顾。

分类
html

解决诡异的 Chrome 自动完成问题

上周末客户突然报告了一个奇怪的 bug:删除用户时,会自动进入搜索结果页。我在我本地试了一下,100% 复现,相当诡异。经过仔细观察,我发现点击删除用户的按钮时,地址栏会发生变化,在新的路由下,会搜索当前用户:

删除用户时的截图

反复重试之后,我认为:是浏览器自动完成的锅。因为删除用户的操作非常敏感,所以我们要求管理员必须输入密码作为校验。而这个界面与常见的用户登录界面非常相像,所以浏览器自作聪明,找了一个 它认为是 用户名的地方填入了用户名,而这个文本框刚好是全局搜索的搜索框:

如图可见搜索框的位置

当其中的内容发生变化时(也即触发了 change 事件),就会跳转到 /search?{key}={query},然后开始搜索。

问题找到后,接下来进入修问题时间。由于是浏览器的锅,Web 前端难以直接触及,所以很难修。经过反复艰难的 Google,终于在这个页面找到了答案:https://support.google.com/chrome/thread/9498749?hl=en(3楼),原来 autocomplete 不止有 onoff 两个可选值,还可以是 usernameemail、或 password,等。(详见 MDN The HTML autocomplete attribute。)于是我尝试给真正的 username 输入框加上 autocomplete 属性,果然问题解决了。

看来以后有时间得再研究一下 autocomplete 属性了,说不定能解决之前为了防止自动补全而做的各种 hack。

分类
npm

几步简单的操作解决 `npm audit` vulnerabilities

NPM 是 JavaScript 生态最重要的组成部分,我们的项目中会大量使用 NPM 安装第三方包(安装后就称为“项目依赖”)解决问题。这些第三方包也会带来他们的依赖,最终一个项目里可能安装成百上千个依赖。

有道是:没有完美的代码,代码里一定藏有隐患。所以用的依赖多了,其中有问题的概率也提升了,三五不时的,npm 就会提示我们:found N low/medium/high severity vulnerabilities

npm 提供命令 npm audit fix,理论上可以修复这些隐患,但在实际操作中,以我的经验来看,并不容易生效。我猜测可能是因为依赖间的复杂关系,想彻底解决并升级不太容易。所以我一般是这样做的:

分类
工具

推荐网页 IM:Drift

可能有些同学注意到了,最近两个月,只要打开这个博客并且稍微浏览一会儿,右下角就会弹出一个聊天框。此时读者就可以跟我聊天,如果我当时在线(打开了管理端),就能看到消息并且实时回复;如果我不在线,可以上线后再回复,读者下次回到博客时,也可以看到消息。

这个工具就是 Drift,它本质上是一个面向商家的网页 IM,支持匿名聊天,方便客户与商家交流。有点类似淘宝旺旺,只不过它可以嵌入任意网站。

实际上我是帮我厂试水,装上之后还真的有人用它咨询问题,然后聊了几句,各方面体验都不错。就很快实装到我厂官网了。

上线之后表现很好,工作日期间每隔一两天就会有人来咨询,而且接下来的进展也都比较理想,大部分可以发展到试用阶段。对比过去几年“联系我们”的邮箱,两者在接待客户方面真是天壤之别。

不过 Drift 也有不少小毛病,比如:因为网站在国外,所以国内的启动速度比较慢;静态资源的缓存设置也有问题,导致每次加载都要很久(我都想去给他们调 CDN 配置了……)。国内的同学可以考虑用去哪儿的 StarTalk,不过从架设难度上比 drift 难用很多、功能弱很多、界面丑很多……

总之,在网页上添加客服 IM 对增加客户有很大帮助,建议大家有机会都搞一下。

分类
css

CSS 网页保持全屏并自动伸长

其实是个小需求,以前也搞过很多次,没想到前几天被坑了一下,记一笔。

以前,如果想要页面在内容任意多的时候都能占满浏览器,可以简单设置:

html,
body {
  height: 100%;
}

但是这样设置,在 Safari 浏览器上,会将 <body> 固定为窗口高度,如果内容多,就会被底部挡住内容。解决方案是 body 高度用 min-height:100%

如果是三行一列的结构,即上面是导航条,下面是脚部,中间随内容自适应,可以用:

body {
  display: flex;
  flex-direction: column;
}

这个时候,不能用 flex-basis,在 Safari 上会失去弹性,也要用 min-height。所以,最终样式大概就是:

html {
  height: 100%;
}

body {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

#nav {
  height: 4rem;
}
#bottom {
  height: 10rem;
}
#content {
  flex-grow: 1;
  min-height: 40rem;
}

另外,因为基本只有桌面浏览器需要这个功能,所以可以考虑加一个 @media (min-width: 576px) 做限制。

分类
http

解决跨域问题笔记

跨域问题常遇常新,每次都觉得再也不会有问题了,结果过几天又会掉进新坑。

因为种种原因,最近一个项目需要跨域请求 API。然后就随手设置了一下,结果 GET 没问题,POST 就不行,很明显是撞到跨域墙上了。

最后发现原因:

  1. 我们启用了 basic auth 验证用户身份
  2. OPTIONS 也会被要求验证
  3. 预请求失败,后面的正式请求就不会发出

趁着还没忘,总结一下跨域的处理过程:

  1. 首先,熟读《MDN HTTP访问控制(CORS)》
  2. 跨域时,复杂请求(除 HEADGETPOST) API 需要返回 CORS 头
  3. 发起复杂请求前,会发送一个 preflight 请求,也就是 OPTIONS,很多坑都在这个请求上
  4. OPTIONS 是浏览器自动发送的,不受我们控制,在开发者工具的 Network 面板里也看不到。我们经常需要模拟它,检查返回是否符合预期。请求头在后面。
  5. OPTIONS 无法处理 Basic auth,如果开了的话,要做特殊处理
  6. 需要返回 Access-Control-Allow-Origin 允许跨域的域名,简单点可以写 *,但如果要上传 cookie,则必须写明域名,且只能是 一个 域名
  7. 所以如果有多个域名要跨域访问 API,需要在服务器端判断来源,并返回不同的域名
  8. 如果要上传 cookie,需要在请求时声明 withCredential: true
  9. 服务器还要返回许可的方法,即 Access-Control-Allow-Methods: GET, DELETE, PATCH 等,让浏览器判断
  10. 如果前面都通过了,浏览器才会发送正式请求。如果正式请求失败,则看不到任何返回。

测试 OPTIONS 请求头

OPTIONS /resource/foo 
Access-Control-Request-Method: DELETE 
Access-Control-Request-Headers: origin, x-requested-with
Origin: https://foo.bar.org
分类
vue

Vue 2020 年路线图,Vue 3.0 计划于 Q2 发布

昨天 Vue 团队更新了 2020 年的路线图,里面包含了很多 Vue 3.0 的信息。建议大家一定要看原文,地址在:https://github.com/vuejs/vue/projects/6。下面我结合自己的理解翻译一下:

FAQ

问:3.0 啥时候能好?

答:请往后看。另外请注意,这些日期仅供参考,我们团队的首要目标是发布生产级别的高质量代码,不是赶 deadline。

问:3.0 里都有啥变化啊?

答:请自行翻阅最新的 RFC。另外,也要注意核心团队提交的 RFC 草案。

如果某个 RFC 里包含破坏性变更,那么里面一定会有“升级策略”章节,讨论迁移问题。

对于现在的 2.x 用户,我们会提供:

  • 迁移向导
  • 能够兼容 2.x 的兼容性版本(如果能兼容的话),并且对该升级的地方给出提示和升级建议
  • 命令行迁移工具
    • 自动升级能升级的代码
    • 不能自动升级的,扫描出来提示手动升级

问:我是新人,我现在该学 Vue 2.0 还是等 3.0?

答:如果你刚刚开始学习框架,那么应该开始使用 Vue 2。我们没有对 Vue 3 进行巨大的重新设计,所以大部分 Vue 2 知识仍将适用于 Vue 3。 如果你打算学习框架,没有必要等待。

如果你要为某个生产级别的项目选择技术栈:

  • 如果项目需要立即动工:我们仍然建议使用 Vue 2,以便获得完整的、框架级别的支持。 但是,也请留心 3.0 中即将发生的更改,不要使用将被移除的功能,最好也不要使用与 Vue 2 深度耦合的第三方依赖。
  • 如果项目可以等到 Q2 末:那我们建议你等等,用 3.0。

问:以后 2.x 会咋样呢?

答:接下来会有一个小版本(2.7)更新:

  • 将兼容的 3.x 功能反向移植回 2.x
  • 对 3.x 弃用的功能发出警告

这是 2.x 最后一个小版本,并提供长达 18 个月的 LTS(长期支持)。即使在 LTS 结束之后,我们也会继续提供重要的安全更新。

问:Vuex 方面有什么计划么?

答:一方面,我们正在开发Vuex(4.0)版本,其 API与 当前版本(3.0)完全相同,但与 Vue 3 兼容。我们力求向下兼容,让用户可以在 Vue 3 项目中继续使用现有 Vuex 代码。

另一方面,我们也在尝试新的设计,更多的利用 Vue 3 的响应式 API,也让 Vuex API 不那么冗长。 这个新版本暂定为“ vuex-next”,也就是 5.0。 眼下,我们只是在进行早期探索,最早也要到 2020 年第三季度才会发布。

2020 一季度计划

  • 3.0 SSR
  • 3.0 迁移
    • 升级向导(施工中)
    • 2.x 兼容版本
    • 迁移工具
  • 3.0 框架
    • router(施工中)
    • Vuex(施工中)
    • 测试工具(施工中)
    • JSX babel 插件(施工中)(我以为不会有这个东西了呢)
    • CLI
    • Devtools
    • 其它(虽然最后三个没标施工中,不过我觉得多半也是在施工中咯)
  • 3.0 beta
    • Q1 末发布!
    • 3.0 核心现在其实已经完成了,我们希望 API 到这个时候也能稳定下来。
    • 我们还需要更多的时间才能更新周边的库和工具。 如果您的使用场景对 router 和 vuex 没有硬性要求,这个时候就可以开始使用 3.0 了,但最好是非关键性应用程序。

2020 二季度计划

  • 继续之前未完成的 3.0 框架工作
  • 季度中,发布 3.0 RC
    • 冻结 API,不再有重大变化。进入 RC 之前,所有涉及到重大变更的 RFC 都要定案。
    • 全家桶能够和 3.0 版本协同工作。
    • 3.0 版本就绪,此阶段基本可用。仍然会有一些小错误和框架集成问题,在 RC 阶段都会慢慢被解决掉。
  • 3.0 发布管理
    • 回归测试
    • 自动化每晚发布
    • 正式确定版本生命周期
  • 3.0 IE11 兼容性版本
  • 3.0 官方正式版

2020 三季度计划

发布 2.7 版本

  • 反相迁移 3.x 功能到 2.x
  • 对 3.x 中弃用的功能发出警告
  • 2.x 最后的小版本,LTS