技术选型
前端:
Angular
优点:声明式 UI、完善的指令系统、双向数据绑定、模块化、依赖注入、完整的 MVC 以及可以自定义的指令
缺点:自带的路由模块功能比较弱,需要依靠第三方的 uiRouter,整体较笨重,不适合做交互频繁的网页,对于一个页面显示数据量较大的网页性能优化是一个问题,还有就是对 SEO 不友好。
事件是 JavaScript 和 HTML 交互的基础,在 W3C 标准出来之前,各个浏览器都有自己的一套事件方法,有的使用事件捕获,有的使用事件冒泡,它们都支持直接在 HTML 元素上绑定事件,这个时候的事件模型被称为 0级DOM。W3C 标准统一之后,对浏览器的事件模型做了一定的前后兼容并新增了一些特性,这个时候的事件模型被称为 2级DOM(没有 1级DOM 是因为在 1级DOM 的标准里没有定义跟事件有关的内容)。
1. What does a doctype do?(doctype 是什么)
doctype 是指网页的文档类型,用来指定这个网页用什么版本的 HTML 或者 XHTML,如果不指定文档类型,代码里的标签和样式就没办法正确地解释出来。
2. What’s the difference between standards mode and quirks mode?(标准模式和怪异模式有什么区别)
标准模式和怪异模式(也称兼容模式)是浏览器的渲染网页的两种标准,W3C 标准普及之后,为了兼容那些年代久远的网页,就采用了两种模式渲染的方式来解决这个问题,一般通过识别网页的 doctype 声明来决定使用哪种模式渲染。这两种模式最大的区别在于对盒模型的定义上,在标准模式中,盒子的 width 等于盒子的内容区的宽度,在怪异模式中,盒子的 width 等于内容区宽度加上边界宽度、内边距和外边距的宽度。
前言:这学期大三了,马上就到了找实习的日子,感谢百度 FEX 开源了一个面试题目库Front-end Job Interview Questions,让我能够审查一遍自己的知识疏漏,这个系列的博文将会根据题库里面的非主观题目做一些力所能及的解释。
1. Can you describe the difference between progressive enhancement and graceful degradation?(描述一下渐进增强和优雅降级的不同)
渐进增强和优雅降级是对待同种事物的两种不同看法,举例来说,渐进增强就是做网站的时候先做一个基础的完整功能,然后针对一些先进的浏览器做一些更加先进的匹配以提升用户体验;优雅降级就是做网站的时候先按照先进浏览器的高标准做,然后再针对一些比较落后的浏览器做一些匹配使它们不会完全无法使用。
在许愿墙开放前夕,我任性地将原来百度云擎四毛钱的套餐升级成了三块钱的套餐,升级的主要动作就是增加执行单元的数量,升级之后出现了一个问题就是 socket.io 有时候不管用了,在许愿墙里 socket.io 我是用来做实时的消息推送和用户之间的实时私信功能的,升级之后出错的具体问题就是有时候跟用户发私信的时候对方并不能实时接收,只能等到下次登录的时候去数据库拿未读消息的时候才能看到。本地调试的时候发现 socket.io 抛出的错误信息是 socket.io connection closed before receiving a handshake response
。几番查询之后发现是由于服务端开了多条进程而进程之间无法通信导致的。这时候我就明白了原来百度云擎增加执行单元的数量就相当于多开了一条独立的进程跑你的后台,从而提高整个服务的性能和负载能力,难怪这么贵。。。
为了解决多进程之间通信的问题,我决定使用 redis 服务器做成一个事件订阅和发布的模型,在网上搜索找到了一篇类似的文章:《利用扩展服务实现基于websocket的聊天室》,不同的是那篇文章使用的是 nodejs-websocket 这个库,我在许愿墙里使用的是 socket.io,两种不同的库做起来方法有所不同,所以这里我打算总结一下在使用 socket.io 的时候如何利用 redis 做一个进程间的消息发布与订阅模块。
在许愿墙最后一天的男生许愿环节中,由于男生数量众多(逃),在一段时间后导致七牛存储的图片挂了,经过查询之后确定是由于获取到的微信 access_token 不正确造成的,报 40001 invalid token 错,因为我的 access_token 是全局缓存在服务器中的,有效期为两个小时,当时我采取的做法是暂时取消全局缓存的策略,采用每次请求一个新 token 的方法来暂时替代,因为考虑到许愿墙的用户数量少而且只是发图片的时候才需要使用到 token,所以即使 token 的获取次数有限制也不会有超出限制的风险。临时修复之后我上网查询后发现,这是一个比较隐藏的原因的造成的:当用户请求比较多的时候,在 token 过期的时候有多个用户同时请求了 token,但是由于网速的问题,导致了一些卡顿,比如 A B 同时请求了新的 token,A 先请求到了 token C,B 后请求到了 token D,此时微信服务器默认正确的 token 应该是 token D,因为多次重复的刷新 token 会使新请求到的 token 覆盖掉前面请求的 token,但是由于返回的时候网络卡顿的原因,本来应该 token C 先返回,token D 后返回的,由于卡顿导致 token D 先返回了,返回之后被存在缓存里,但随后 token C 紧随其后也来到了服务器,这时候 token C 也被写入了缓存覆盖掉了 token D,这时候错误就产生了,服务器缓存里此时存着的是不被微信服务器承认的 token,所以使用这个缓存的 token 去做任何操作都会导致 token 错误被抛出,我在许愿墙遇到的问题也是由此产生的,解决办法就是清除此时的缓存,让服务器去请求全新的有效的 token 重新缓存,我上面的做法并不值得提倡,因为我是基于用户数少考虑并且当时还不清楚具体出错原因考虑的。推荐的方法还是手动清除缓存。
通过微信 SDK 选择了本地图片后,在 AngularJS 应用中无法通过把 localId 赋值给 img 的 ng-src 属性进行预览,但是当直接赋值给 img 标签的 src 属性时却可以正常预览。出现这个问题是的原因是 AngularJS 自身的安全策略,为了避免别人通过图片 link 发起 XSS 攻击,凡是通过 ng-src 指令给元素赋值的在编译阶段都会进行 src 路径合法性的检查,并且由 Angular 维护着一份正则表达式形式的白名单,只有 src 符合白名单里的要求的才被允许赋值,否则都会使这个 src 无效并在前面加上一个 unsafe 标记。所以这个问题的解决办法就是修改本地的白名单,让微信的 localId 不被 Angular 当做不安全的 url,具体代码如下:
1 | var app = angular.module('myApp', []); |
总体思路是:在微信下选好图片后将图片上传到微信服务器,在后端使用微信服务器返回的图片 serverId 加上调用接口的 ApiTicket 通过七牛的 fetch 接口向微信服务器下载多媒体文件的接口请求图片的二进制流,然后保存至自己七牛账号内的特定 bucket。
大致过程如下: