CHROME开发者工具的小技巧

20 | 04 | 2017

Chrome的开发者工具是个很强大的东西,相信程序员们都不会陌生,不过有些小功能可能并不为大众所知,所以,写下这篇文章罗列一下可能你所不知道的功能,有的功能可能会比较实用,有的则不一定,也欢迎大家补充交流。

话不多话,我们开始。

代码格式化

有很多css/js的代码都会被 minify 掉,你可以点击代码窗口左下角的那个 { }  标签,chrome会帮你给格式化掉。

强制DOM状态

有些HTML的DOM是有状态的,比如<a> 标签,其会有 active,hover, focus,visited这些状态,有时候,我们的CSS会来定关不同状态的样式,在分析网页查看网页上DOM的CSS样式时,我们可以点击CSS样式上的 :hov 这个小按钮来强制这个DOM的状态。

 

 

动画

现在的网页上都会有一些动画效果。在Chrome的开发者工具中,通过右上角的菜单中的 More Tools => Animations 呼出相关的选项卡。于是你就可以慢动作播放动画了(可以点选 25%10%),然后,Chrome还可以帮你把动画录下来,你可以拉动动再画的过程,甚至可以做一些简单的修改。

 

直接编辑网页

在你的 console 里 输入下面的命令:

1
document.designMode = "on"

于是你就可以直接修改网页上的内容了。

P.S. 下面这个抓屏中还演示了一个如何清空console的示例。你可以输入 clear() 或是 按 Ctrl+L(Windows下),CMD + K (Mac下)

 

网络限速

你可以设置你的网络的访问速度来模拟一个网络很慢的情况。

 

复制HTTP请求

这个是我很喜欢 的一个功能,你可以在 network选项卡里,点击 XHR 过滤相关的Ajax请求,然后在相关的请求上点鼠标右键,在菜单中选择: Copy => Copy as cURL,然后就可以到你的命令行下去 执行 curl 的命令了。这个可以很容易做一些自动化的测试。

 

友情提示:这个操作有可能会把你的个人隐私信息复制出去,比如你个人登录后的cookie。

抓个带手机的图

这个可能有点无聊了,不过我觉得挺有意思的。

在device显示中,先选择一个手机,然后在右上角选 Show Device Frame,然后你就看到手机的样子了,然后再到那个菜中中选 Capture snapshot,就可以抓下一个有手机样子的截图了。

我抓的图如下(当然,不是所有的手机都有frame的)

 

设置断点

除了给Javascript的源代码上设置断点调试,你还可以:

给DOM设置断点

选中一个DOM,然后在右键菜单中选 Break on … 你可以看到如下三个选项:

给XHR和Event Lisener设置断点

在 Sources 面页中,你可以看到右边的那堆break points中,除了上面我们说的给DOM设置断点,你还可以给XHR和Event Listener设置断点,载图如下:

关于Console中的技巧

DOM操作
  • chrome会帮你buffer 5个你查看过的DOM对象,你可以直接在Console中用 $0, $1, $2, $3, $4来访问。
  • 你还可以使用像jQuery那样的语法来获得DOM对象,如:$("#mydiv")
  • 你还可使用 $$(".class") 来选择所有满足条件的DOM对象。
  • 你可以使用 getEventListeners($("selector")) 来查看某个DOM对象上的事件(如下图所示)。

  • 你还可以使用 monitorEvents($("selector")) 来监控相关的事件。比如:
1
monitorEvents(document.body, "click");

Console中的一些函数

1)monitor函数

使用 monitor函数来监控一函数,如下面的示例

2)copy函数

copy函数可以把一个变量的值copy到剪贴板上。

3)inspect函数

inspect函数可以让你控制台跳到你需要查看的对象上。如:

更多的函数请参数官方文档 – Using the Console / Command Line Reference

Console的输出

我们知道,除了console.log之外,还有console.debugconsole.infoconsole.warnconsole.error这些不同级别的输出。另外一个鲜为人知的功能是,console.log中,你还可以对输出的文本加上css的样式,如下所示:

1
console.log("%c左耳朵", "font-size:90px;color:#888")

于是,你可以定义一些相关的log函数,如:

1
2
3
4
5
6
console.todo = function( msg){
  console.log( '%c%s %s %s', 'font-size:20px; color:yellow; background-color: blue;', '--', msg, '--');
}
console.important = function( msg){
  console.log( '%c%s %s %s', 'font-size:20px; color:brown; font-weight: bold; text-decoration: underline;', '--', msg, '--');
}

关于console.log中的格式化,你可以参看如下表格:

指示符 输出
%s 格式化输出一个字符串变量。
%i or %d 格式化输出一个整型变量的值。
%f 格式化输出一个浮点数变量的值。
%o 格式化输出一个DOM对象。
%O 格式化输出一个Javascript对象。
%c 为后面的字符串加上CSS样式

 

除了console.log打印js的数组,你还可以使用console.table来打印,如下所示:

1
2
3
4
5
6
7
var pets = [
  { animal: 'Horse', name: 'Pony', age: 23 },
  { animal: 'Dog', name: 'Snoopy', age: 13 },
  { animal: 'Cat', name: 'Tom', age: 18 },
  { animal: 'Mouse', name: 'Jerry', age: 12}
];
console.table(pets)

 

关于console对象

  • console对象除了上面的打日志的功能,其还有很多功能,比如:
  • console.trace() 可以打出js的函数调用栈
  • console.time() 和 console.timeEnd() 可以帮你计算一段代码间消耗的时间。
  • console.profile() 和 console.profileEnd() 可以让你查看CPU的消耗。
  • console.count() 可以让你看到相同的日志当前被打印的次数。
  • console.assert(expression, object) 可以让你assert一个表达式

这些东西都可以看看Google的Console API的文档

其实,还有很多东西,你可以参看Google的官方文档 – Chrome DevTools

关于快捷键

点击在 DevTools的右上角的那三个坚排的小点,你会看到一个菜单,点选 Shortcuts,你就可以看到所有的快捷键了

如果你知道更多,也欢迎补充!

转自:酷 壳 

e98534b3331ebfc70a25

2016年崛起的JS项目

17 | 04 | 2017

近几年 JS 社区创新和演化的速度是有目共睹的,几个月前比较时髦的技术很可能现在已经过时了。2016 已经过去,你有没有担心错过了什么重要的内容?在这篇调查报告中我们会为你解读社区的主流趋势。

我们将从数量上来分析哪些项目 2016 年获得比较多的关注,具体的做法是比较各项目 2016 年在 Github 上新增 star 的数量。

回顾 2015 年:React 无疑占据了统治地位,而 Redux 则在众多牛毛的 Flux 实现中脱颖而出。那么 2016 年哪些项目最受开发者关注呢?

目录

  1. 最受欢迎项目
  2. 前端框架
  3. Node.js 框架
  4. React 项目模板
  5. 移动开发
  6. 编译工具
  7. 构建工具
  8. 测试框架
  9. IDE
  10. 静态网站生成器

1. 最受欢迎项目

仔细观察 2016 年排名前 10 的项目,你就能对 WEB 社区的演化方向有个直观的把握,概括如下:

 

上面这些项目覆盖的领域,无疑证明了 JS 的通用性,印证了那句话:能被 JS 编写的,迟早都会被 JS 编写

2016 年的最佳项目是… 🏆

Vue.JS 2016 年新增超过 25000 个 star,意味着平均每天新增 72 个 star,超过了所有同类项目的流行速度,比如 React 和 Angular。 采用 Virtual DOM 来增强性能的 Vue.JS v2 于 2016 年 10 月发布。

Vue.JS 已经被不少大公司用在了生产环境中,比如中国最大的电子商务网站里巴巴,所以你可以将 Vue.JS 作为一个安全的选择。

围绕着 Vue.JS 的社区生态也日趋成熟,包括路由库(vue-router)和状态管理库(Vuex)。 Vue.JS 兼具了 ReactAngular 1 两者的优点,其中 React 的基本思想是组件式开发,而 Angular 1 是模板增强。

2. 前端框架

前端框架的百花齐放也许是出现 JS 疲劳 的原因所在,新的框架、工具和库层出不穷,把创新的车轮推向前进。

概括来讲,前端框架可以分为两大类:

  • 大而全的框架,包括创建现代 WEB 应用的所有功能特性,比如路由、数据获取、状态管理,典型项目有:Angular 1Angular 2EmberAurelia
  • 小而美、聚焦在 UI 层面的解决方案,典型项目有 ReactVue.JSInferno

前文中我们已经探讨了排名第 1 的项目 Vue.JS,下面来看看其他竞争者:

React 及其竞争者

React 排名第 2,所有开发者都知道 React 有着庞大的社区和完整的生态系统。

React 设计思想非常流行,受 React 启发而诞生了大量类 React 项目,这些项目继承 React 优点的同时有非常大的改进,比如各种能提高性能和缩短构建时间的瘦身版本。

Inferno 在类 React 项目中是最受欢迎的,它自己则标榜是所有竞争者中性能最快的。

Preact 也是一个非常不错的选择,它也有不错的生态,比如各种脚手架、路由,甚至还有一个 compact 模块让任何能在 React 环境运行的库在 Preact 中运行。

 

Angular 1 和 Angular 2

Angular 项目已经被拆分成两个仓库,因为 Angular 2 几乎是 Angular 1 的全面重写,虽然两者在部分概念上是相同的。

Angular 2 全部用 TypeScript 编写,这样它利用 ES6 语法特性提供了现代的、全面的 WEB 框架。

Angular 1 (在 Github 上称作 “AngularJS”) 目前仍然被大量的项目使用,目测会持续流行一段时间。

此外,不得不提的 Ember, 虽然社区和生态都很大,但是没有排到前 10 名。

整体来看,相比于那些开箱即用的大而全的框架,开发者更青睐自己组合使用那些小而美的轻量级解决方案,因为这样给了他们更大的自由度。

3. Node.js 框架

2016 年创建和部署 Node.js 应用变得空前的容易,比如下面这些解决方案:

类似于 Gomix 的项目则把 Node.js 的门槛降到不能再低,只要通过浏览器简单的点击拖拽就都能轻而易举的编写分享 Node.js 代码。

那么,如果想创建一个 WEB 应用,我们该选哪个框架呢?

Express

Express 已经成为开发 Node.js WEB 应用的标准框架,大多数工程师都很熟悉他的设计思想(极简的内核,但能让你用各种中间件来扩展他的功能)。

Koa

Koa,设计思想非常类似 Express,区别在于它是使用 ES6 中的 generator 编写的,这种写法解决了大家所熟知的回调地狱 问题。

Feathers

Feathers,是用来实现面向服务架构的一种灵活的解决方案,非常适合创建 Node.js 微服务。

Nodal

Nodal,用来创建基于 PostgreSQL 的无状态的、分布式的服务。

Keystone

Keystone,是我所知的快速搭建基于 MongoDB 的管理后台的最佳解决方案,Keystone.js 基于数据模型的定义即可自动生成后台界面,支持常见的增删改查操作和灵活的数据过滤。

Sails

Sails,是一个全能的 MVC 框架,主要是受到 Ruby on Rails 启发,他已经存在很长时间,支持各种数据库,不管是 SQL 还是 No-SQL。

Loopback

Loopback,内置了很多特性的成熟框架,支持基于 token 的认证,支持各种数据库。 Loopback 的“杀手锏”功能是 API 浏览器,该功能能让开发者用非常直观的方式查看所有的 API 接口,如果你需要创建 API 服务的话,它无疑是个很好的选择。

4. React 项目模板

React 是非常棒的 UI 库,但是基于现代 WEB 应用开发工作流创建 React 应用时仍然需要大量的配置才能把所有的部分拼凑到一起,如何创建一个“真实”的 React 应用呢?各种 React 项目模板(boilerplates)和启动工具箱(starter kits)就是来解决这个问题的,典型的有下面几个:

Create React App

Facebook 开源的,轻量级的解决方案,使用 Create React App 创建 React 应用非常的简单。Create React App 的作者 Dan Abramov (也是 Redux 的作者,目前供职于 Facebook) 在功能丰富和简单可靠之间取得了很好的平衡,没有酷炫的样式解决方案 (仅需纯粹的 CSS) ,没有服务端渲染,但是 React 应用开发的其他方面都浑然一体,开发者体验也非常棒。

相比于同类工具,如果你使用了 Create React App,它会成为你项目的依赖,所有的黑科技都是不可见的,你只能看到你自己的应用代码,你可以随时更新这个依赖。

React boilerplate

React boilerplate 则包含了 React 应用所需的一切,包括 Redux 以及基于 Web Worker 实现的离线功能。使用它可以创建“渐进式 Web 应用”(亦称“PWA”),如果想了解更多 PWA 的知识,可以阅读 Nicolás Bevacqua 的 这篇文章

Next.js

Next.js, 由来自 Zeit 的 busy folks 创建,支持服务端渲染,可以用来创建 universal 应用(或者“同构应用”),直白点说,这种应用的前后端可以运行相同的代码。

5. 移动开发

JS 的通用性是毋庸置疑的,现如今可以用 WEB 工程师非常熟悉的技术(HTML、JS、CSS)构建 Native 移动应用。下面是几个典型的解决方案:

React Native

使用 React Native,可以用类似于 React 思路,用同一份代码构建出支持 iOS 和 Android 平台的、真正的 Native 应用,想了解如何构建跨平台的更多内容?建议阅读这篇教程。

其他基于 Cordova 的方案多使用 Webview 来渲染页面,相比于 Native 应用运行时性能会大打折扣,不过,开发者那种 “Write Once Run Everywhere” 的梦想终于成真了!

Ionic

Ionic 是 “hybird” 应用开发领域的先锋,底层基于 Cordova 来访问移动设备的系统功能,社区和生态系统非常成熟。

NativeScript

NativeScriptReact Native 的目标是相同的,即基于 WEB 技术构建 Native 应用,其核心分为两部分:NativeScript 内核,NativeScript + Angular 2。

展望未来…

Weex 是 2017 年需要密切留意的项目,他是基于 Vue.JS 的、用来创建跨平台移动应用的框架。

6. 编译工具

我们这里讨论的是把其他语言或者 JS 变体编译(Compiler)或转换成(Transpiler)标准 JS 代码的工具,这些工具生产出来的代码可以在浏览器或者 Node.js 环境中执行。

最常见的场景是,这类编译工具能够让开发者使用 ES6 语法编写代码,而不用担心浏览器支持情况。

TypeScript

最具潜力的编译工具可能是 TypeScript 了,它为 JS 带来了类似于 Java 和 C# 的静态类型,而 Angular 2 完全使用 TypeScript 的事实让他看起来更诱人,当然关于在 JS 使用静态类型的讨论有很多,建议阅读下面这两篇文章来做出自己的决定:

Babel

Babel + webpack 已经成了 ES6 代码转换、React 模板编译的标准工具组合,Babel 最初是用来编译 ES6 的,但得益于他的插件系统,如今俨然已经演化成一个用途广泛,几乎能实现各种代码转换的工具。

 

Flow

Flow 并不是一个编译工具,它只是一个基于 JS 代码标记的静态类型检查工具,也就是说,使用 Flow 时需要在代码中添加各种注释来注明需要的数据类型,关于 Flow 的使用,可以阅读这篇文章

Flow 在很多 Facebook 项目的源代码中都有使用,而 Facebook 已经成为开源社区的重要玩家,开源了 ReactReact NativeFluxImmutableJest 等众多的项目,相信你明白这意味着什么。

CoffeeScript

CoffeeScript 的简洁语法大量借鉴了 Python 和 Ruby 的语言特性,过去几年曾经是最受欢迎的编译器,但 2016 年很多开发者从 CoffeeScript 转向了 ES6 + Babel 组合。

 

7. 构建工具

2016 年“构建过程”似乎成了 WEB 项目的标配,如果一个 WEB 应用没有构建过程则是难以想象的事情,在构建过程中通常你需要做编译模板、静态资源合并压缩之类的事情,以为生产环境做好准备。

Webpack

Webpack 是构建单页应用(SPA)的主要工具,它和 React 生态结合的非常好,最新发布的 Webpack 2 带来了不少非常有前景的改进,具体可以阅读这里

Gulp

Gulp 是一个通用的任务运行工具,可以在任何和文件系统打交道的自动化流程中使用,可以认为它并不是 WebpackBrowserify 的直接竞争者。

Grunt 类似,Gulp 的主要角色是任务管理,你可以让它压缩合并代码,但是它不会帮你处理 JS 模块化问题,而 WebpackBrowserify 是可以的。

当然了,Gulp 可以和 Webpack 结合起来使用,即使开发者倾向于使用 npm script 也是可以的,实际上很多开发者就是这么做的。

Browserify

Browserify 因为非常简单,在 Node.js 工程师群体中比较受欢迎。简单来说,它把多个 Node.js 的包作为输入,然后输出单个编译后的文件。相比而言,Webpack 在 WEB 应用打包方面考量更多,更适合现代的 WEB 开发工作流。

展望未来…

2017 年需要留意的模块打包工具是 rollup,它强调的是性能,基于 ES6 的模块规范,并且支持 Tree Shaking 这种黑科技,构建产生的结果只包含实际业务逻辑用到的代码,而不是简单的文件合并。

8. 测试框架

相比于流行了很久的测试框架 JasmineMocha,2016 年出现了 2 个更新的、并有很多人使用的测试框架:AVAJest

AVA

AVA 由非常高产的 Sindre Sorhus 开发和维护,其标榜的重点是性能和 ES6,能够并行的运行测试。AVA 的语法非常类似 TapeNode-tap

Jest

Jest,又一个 Facebook 开源项目,最近几个月引起了大量的开发者注意,在 React 社区更加流行,并且越来越多的人开始迁移到 Jest,可以阅读这个故事,2017 年 Jest 极有可能成为最受欢迎的测试框架。

Jest 内置了非常强大的 Mock 特性,而其他的测试框架通常需要依赖第三方的 Mock 包,比如 Sinon.JS

9. IDE

说到 IDE(集成开发环境,Integrated Development Environment),令人振奋的是最受欢迎的 2 款 IDE 都是用 WEB 技术开发的开源项目。

Visual Studio Code

微软的 Visual Studio Code 在 WEB 开发者群体中非常受欢迎,因为他提供了非常棒的 TypeScript 和 Node.js 集成,部分开发者甚至特别提到 Visual Studio Code 的智能感知功能极大的提高了开发效率。现在把微软和开源放在一起,终于不那么违和了

Atom

Atom 由 Github 开源,使用 Electron 构建,在受欢迎程度上并没有落后 Visual Studio Code 太多,关于 Atom 的一个有趣事实是,他所使用的主要语言是 CoffeeScript。

10. 静态网站生成器

静态网站生成器(SSG)是指能够生成一大坨 HTML、CSS、JS 文件方便你快速部署到简单的 WEB 服务器上而不用安装和配置数据库的工具。就像 Gatsby 所标榜的:

像 1995 年那样构建网站。

静态网站的特点是速度快、健壮行高、容易维护。

静态网站如此流行的重要原因是市面上有很多非常好用并且免费的静态网站托管解决方案,比如:

Hexo

2016 年最流行的静态网站生成工具是 Hexo,他有点类似于 Workdpress 这样的 CMS 系统,可以用来方便的创建博客网站,他还有很多其他的特性,比如国际化插件。

Gatsby

新玩家 Gatsby 是一个比较有趣的解决方案,相比于竞争者优秀的地方在于:它使用 React 生态系统来生成静态文件,可以组合 React Component、Markdown 和服务端渲染来完成静态网站生成让他更强大。

 

总结和展望

虽然 2016 年出现了“JS 疲劳”,也发生了戏剧性的事件(如 “leftpad 门”),但总体来讲 2016 年对 JS 社区来说是非常重要的一年,部分项目在 2016 年崛起,如 Vue.JSReact Native,还有些黑马项目 2016 年诞生,如 YarnCreate React App

我们谈论了 2016 年 Github 上最受瞩目的开源项目,但是真正重要的是开发者的满意度,如果你想就这个话题有更量化的认识,建议去看看 Sacha Greif 的调查 State of JavaScript,该调查收集了超过 9000 份问卷。

接下来该思考 2017 年了,哪些将会持续获得开发者的青睐?哪些会成为新星呢?下面是我精选的 10 个我 2016 年比较欣赏,并且 2017 年会继续保持增长的项目或创意:

  • Vue.JS:还在快速增长阶段
  • Electron
  • Create React App
  • React Native
  • Gatsby (你浏览的这个页面就是用它来构建的)
  • Yarn:快速、可靠并且安全的依赖管理工具,可以直接替代 npm,建议阅读文章 yarn vs npm
  • PWA(Progressive Web Applications)渐进式 WEB 应用
  • Node.js 微服务的一站式部署和运行解决方案,比如 Now
  • Node.js 的进化:最新版本对 ES6 语法的支持已经非常好了
  • 最后是 GraphQL:我身边不少朋友说这会是一个大的进步

感谢你花时间阅读本文,可以尽情把本文分享出去,有疑问可以到 Github 上发起 Issue 或直接联系我们。

best-practice

编写 Node.js Rest API 的 10 个最佳实践

13 | 03 | 2017

Node.js 除了用来编写 WEB 应用之外,还可以用来编写 API 服务,我们在本文中会介绍编写 Node.js Rest API 的最佳实践,包括如何命名路由、进行认证和测试等话题,内容摘要如下:

1. 正确使用 HTTP Method 和路由

试想你正要构建一个 API 用来创建、更新、获取、删除用户,对于这些操作,HTTP 规范里面已经有了现成的操作:POST、PUT、GET、DELETE,建议直接使用他们来描述接口的行为。

至于路由的命名,应该使用名词或名词性短语来作为资源标识符,比如上文提到的用户管理的例子,路由就应该长这样:

  • POST /users 或者 PUT /users/:id 用来创建新用户;
  • GET /users 用来获取用户列表;
  • GET /users/:id 用来获取单个用户;
  • PATCH /users/:id 用来更新用户信息;
  • DELETE /users/:id 用来删除用户;

2. 正确的使用 HTTP 状态码

如果服务器端在请求处理的过程中出错了,你必须设置正确的响应状态码,具体如下:

  • 2xx,表示一切正常;
  • 3xx,表示资源位置已经更改;
  • 4xx,表示因为客户端错误而导致请求无法被处理,比如参数校验没通过;
  • 5xx,表示因为服务器错误导致请求无法被处理,比如服务端抛了异常;

如果你使用 express,设置状态码非常简单:res.status(500).send({ error: ‘Internal server error happend’ }),如果使用了 restify,也是类似的:res.status(201)。

如果想看完整的 HTTP 状态码,点击这里

3. 使用 HTTP Header 来发送元数据

如果想要发送关于响应体数据的元数据,可以使用 Header ,Header 可以包含的常见元数据包括如下几类:

  • 分页信息;
  • 频率限制信息;
  • 认证信息;

如果你需要在 Header 中发送自定义的元数据,最好的做法是在 Header 名称前面加 X,例如,需要发送 CSRF Token 的时候,实际的 Header 应该命名为:X-CSRF-Token,然而,这种 Header 在 RFC 6648 中已经被废弃了。API 在设置自定义 Header 的时候还要尽可能避免命名冲突,比如为了达到这个目的OpenStack 为所有 API 的自定义 Header 都加上了 OpenStack 的前缀:

需要注意的是,虽然 HTTP 规范中没有规定 Header 的大小,但是 Node.js 中 Header 的大小被限制在了 80KB。官方原文如下:

4. 为 REST API 挑选合适的框架

根据你的实际场景挑选合适的框架是非常重要的,Node.js 中的框架大致介绍如下:

Express、Koa、HAPI

ExpressKoaHAPI 主要是用来构建浏览器 WEB 应用,因为他们都支持服务端模板渲染,虽然这只是他们众多功能中的一个。如果你的应用需要提供用户界面,那么这三个就是不错的选择。

Restify

Restify 是专门用来创建符合 REST 规范的服务的,他诞生的目的就是帮你构建严格意义上的、可维护的 API 服务。Restify 内置了所有请求处理函数的 DTrace 支持。并且已经被 npmnetflix 用来在生产环境提供重要的服务。

5. 要对 API 进行黑盒测试

测试 API 的最好办法是对他们进行黑盒测试,黑盒测试是一种不关心应用内部结构和工作原理的测试方法,测试时系统任何部分都不应该被 mock。

supertest 是可以用来对接口进行黑盒测试的模块之一,下面是基于测试框架 mocha编写的一个测试用例,该用例的目的是检查接口是否能返回单条的用户数据:

可能有人会问:API 服务所连接的数据库里面的数据是如何写进去的呢?

通常来说,你写测试的时候,要尽可能不对系统状态做假设,然而在某些场景下,你需要准确的知道系统当前所处的状态以增加更多的断言来提高测试覆盖率。如果你有这种需求,你可以试用如下的方法对数据库进行预填充:

  • 选择生产环境数据的子集来运行黑盒测试;
  • 运行黑盒测试之前把手工构造的数据填充到数据库中。

此外,有了黑盒测试并不意味着不需要单元测试,针对 API 的单元测试还是需要编写的。

6. 使用基于 JWT 的无状态的认证机制

因为 Rest API 必须是无状态的,因此认证机制也需要是无状态的,而基于 JWT(JSON Web Token) 的认证机制是无状态认证机制中的最佳解决方案。

JWT 的认证机制包含三部分:

  1. Header:包含 token 的类型和哈希算法;
  2. payload:包含声明信息;
  3. signature:JWT 实际上并不是对 payload 进行加密,只是对其做了签名;

为 API 添加基于 JWT 的认证机制也非常的简单,比如下面的代码:

有了如上的代码,你的 API 就有了 JWT 的保护。如果要访问这种被保护的接口,需要使用 Authorization Header 来提供 token,比如:

你可能注意到了,JWT 模块并不依赖任何数据存储层,这是因为 token 本身是可以单独被校验的,token 里面的 payload 甚至可以包含 token 的签名时间、有效期限。

此外,你还需要确保,所有的 API 接口只能通过更安全的 HTTPS 链接来访问。

7. 学会使用条件请求机制

条件请求机制是基于不同的 Header 表现出不同的行为的机制,可以认为这些 Header 就是请求处理方式的先决条件,如果条件满足,请求处理方式就会有所不同。

可以利用这些 Header 检测服务器上的资源版本是否匹配特定的资源版本,这些 Header 的取值可以是如下的内容:

  • 资源的最后修改时间;
  • 资源的标签(随资源变化而变化);

具体来说:

  • Last-Modified:标识资源的最新修改时间;
  • Etag:标识资源的标签;
  • If-Modified-Since:结合 Last-Modified Header 使用;
  • If-Non-Match:结合 Etag 使用;

下面来看一个实际的例子:

客户端不知道 doc 资源的任何版本,所以请求时即不能提供 If-Modified-Since,也不能提供 If-Non-Match 两个 Header,然后服务端在响应中会增加 Etag 和 Last-Modified 两个 Header。

nodejs-resftul-api-with-conditional-request-without-previous-versions.png
接下来,客户端再次请求相同的资源的时候,就可以带上 If-Modified-Since 和 If-Non-Match 这两个 Header 了,然后如果服务器端会检查资源是否修改,如果没有修改,直接返回 304 – Not Modified 状态码,而不重复发送资源的内容。

nodejs-resftul-api-with-conditional-request-with-previous-versions.png

8. 拥抱接口调用频率限制(Rate-Limiting)

频率限制是用来控制调用方有对接口发起请求的次数,为了让你的 API 用户知道他们还剩下多少余额,可以设置下面的 Header:

  • X-Rate-Limit-Limit:特定时间段内允许的最多请求次数;
  • X-Rate-Limit-Remaining:特定时间段内剩余的请求次数;
  • X-Rate-Limit-Reset:什么时候请求频率限制次数会重置;

大多数的 WEB 框架都支持上面这些 Header,如果内置不支持,也可以找到插件来支持,比如,如果你使用了 koa,可以使用 koa-rate-limit

需要注意的是,不同的 API 服务提供商频率限制的时间窗差异会很大,比如 GitHub 是 60 分钟,而 Twitter 是 15 分钟。

9. 编写良好的 API 文档

编写 API 的目的当然是让别人使用并受益,提供良好的接口文档至关重要。下面这两个开源项目可以帮你创建 API 文档:

如果你愿意使用第三方文档服务商,可以考虑 Apiary

10. 对 API 技术演化保持关注

过去几年中,API 技术方案领域出现了两种新的查询语言,分别是 Facebook 的 GraphQL 和 Netflix 的 Falcor,为什么需要他们呢?

试想这种 API 接口请求:/org/1/space/2/docs/1/collaborators?include=email&page=1&limit=10,类似的情况会让 API 很快失控,如果你希望所有接口能返回类似的响应格式,那么 GraphQL 和 Falcor 就能帮你解决这个问题。

关于 GraphQL

 

关于 Falcor

 

能带来灵感的优秀 API 设计

如果你正在开发 Rest API 或者准备改进老版本的 API,这里收集了几个在线上提供服务、设计优秀并且非常直接借鉴的 API:

QQ截图20170310111400

ES6语言特性的总结(1)

10 | 03 | 2017

虽然在编写项目的过程中,也会用到ES6的语法以及新特性。但感觉学习的不是特别系统,索性这两天重新刷了一下Understanding The ES6,也对ES6有了更深的理解。这里,针对感觉应用比较多,知识点比较重要的部分做了一下总结。内容有点多,因此预计将分为三个部分。

块级绑定-作用域

在ES5中,有一个知识难点,就是变量提升和作用域。而这一部分之所以让人困扰,则是因为JS中变量的声明方式会影响变量实际的创建位置。

有一条规则是:使用var关键字声明的变量,无论其实际声明位置在何处,都会被声明与函数的顶部,这就是变量提升(hosting)。

ES6中为了让变量的生命周期更加可控,引入了块级声明。即,让所声明的变量在指定块的作用域外无法被访问。ES6主要引入了两个新的关键字,letconst

let

letvar类似,不同是的,let声明的变量不会存在变量提升的情况。因此,下面这个代码中:

是无法访问到a变量的。

另一个限制的地方是,禁止重复声明相同的变量。

上面的代码也会报错。

const

这个关键字也是限制了变量提升以及重复声明,而且变量值是不可更改的。

但是,如果绑定的是对象,可以更改对象属性值。

暂时性死区

利用letconst声明的变量,代码在访问到声明处前都是禁止访问的。

循环中的let和const声明

请看下面这段代码:

使用var声明的变量,会在每次循环中被共享了。因此,在循环内部创建的函数都用于同一个变量的引用。通常解决这种方式,在ES5中会采用闭包的方式。而ES6中,可以使用let关键字

这是因为let关键字在每次循环中,都会创建一个新的i变量,而循环内部的函数获取的i变量其实都是副本。

const关键字不可以用在传统的for循环中,但是可以用在for...offor … in语法中。使用效果和let一样。

函数

ES6中对函数的功能做了新的扩展,使之使用起来更方便。

箭头函数

自从有了箭头函数,在遇到回调函数写法的时候,就特别方便。当然它的功能肯定不止于此。箭头函数的语法像这样:

是传统函数写法的一种便捷写法,同时,有以下几个特点:

  1. 不允许重复的具名参数
  2. 没有arguments对象
  3. 不能更改this,在整个函数声明周期内其值会保持不变,因此,在遇到this问题时,不用再像ES5之前的时期使用类似var self =thisbind(this)之类的方法了。
  4. 不能被new调用
  5. 没有this、super、arguments、也没有new.target绑定

默认参数和不具名参数

先看下面这个例子,同时使用了默认参数和不具名参数(也叫做剩余参数):

采用了默认参数值时,仍然可以使用arguments对象来反应真实函数的调用状态, 而arguments对象也可以和不具名参数进行协同工作。

同时,函数的默认值甚至可以利用函数来动态生成,而非写死的,如:

需要注意的是,函数的不具名参数是不能够在对象的setter上使用的,这是因为setter只接受单一值作为它的参数。

扩展运算符

这三个点运算符用在函数声明的时候,就是不具名参数,但是它同时也能用在解构对象上,因此,在函数调用过程中,可以使用该运算符,进行多个参数传递。如

new.target

这是ES6函数对象的元属性,可以通过检查new.target对象是否被定义,可以判断函数是否通过new进行调用。

原理方面,其实就是当函数的构造器(constructor)方法被调用时,new.target 会被填入 new 运算符的作用目标,该目标通常是新创建的对象实例的构造器,并且会成为函数体内部的 this 值。而若call方法被执行的时候, new.target 的值则会是undefined

解构

解构的意思是将数据结构分解为更小的部分,而ES6中引入了解构的方式目的就是能够更好地提取数据。

##对象解构
直接上例子:

以上需要注意的是,当解构赋值表达式的右侧( = 后面的表达式)的计算结果为 null 或 undefined 时,会抛出错误。

##数组解构

数组解构时,解构作用在数组内部的位置上,而不是作用在对象的具名属性上。

参数解构

需要注意的是默认情况下调用函数时未给参数解构传值会抛出错误。但若你要求它是可选的,可以给解构的参数提供默认值来处理这种行为。

扩展的对象功能

在ES6中也对对象的使用方式做了进一步的扩展,使其无论是在代码编写形式层面还是底层操作对象的层面都有了更多的特性。

对象类别

在ES6规范中,定义了对象的每种类别:

1.普通对象:拥有JS对象所有默认的内部行为

2.奇异对象:有别于默认的内部行为的对象

3.标准对象:是在ES6中被定义的对象,可以是普通对象也可以是奇异对象。

4.内置对象:在脚本开始运行时由JS运行环境(浏览器或Node)提供的对象。所有标准对象都是内置对象。

属性初始化器

当对象的一个属性名称与本地变量名相同的时候,可以省略冒号和值,如:

方法简写

方法简写如下:

需要注意的是,使用方法简写,在方法内部可以使用super方法,而传统的写法是无法使用的。

计算性属性名

属性名可以使用拼接的写法,如:

对于某些需要动态生成属性名的场合,写法更加方便。

Object.is方法

为了避免在对象比较过程中的强制对象转换。通常该方法的运行结果和===一样,但是+0-0,NaNNaN不相同。

Object.assign(source, target) 方法

该方法接受一个接收者,以及任意数量的供应者,并会返回接收者。我通常在使用的时候,用来做继承或者说深度拷贝??。

Object.assign() 方法接受任意数量的供应者,而接收者会按照供应者在参数中的顺序来依次接收它们的属性。这意味着在接收者中,第二个供应者的属性可能会覆盖第一个供应者的。

关于重复的对象字面量属性

ES6 移除了重复属性的检查,严格模式与非严格模式都不再检查重复的属性。当存在重复属性时,排在后面的属性的值会成为该属性的实际值。

自有属性的枚举顺序

1.所有的数字类型键,按升序排列。

2.所有的字符串类型键,按被添加到对象的顺序排列。

3.所有的符号类型键,也按添加顺序排列。

修改对象的原型

对象原型的实际值被存储在一个内部属性[[Prototype]] 上, Object.getPrototypeOf() 方法会返回此属性存储的值,而 Object.setPrototypeOf() 方法则能够修改该值。ES6 通过添加 Object.setPrototypeOf()方法而改变了这种假定,此方法允许你修改任意指定对象的原型。它接受两个参数:需要被修改原型的对象,以及将会成为前者原型的对象。
因为这个特性的添加,可以使用 super 进行简单的原型访问。super 是指向当前对象的原型的一个指针,实际上就是 Object.getPrototypeOf(this) 的值。这个功能在使用ES6类的继承的时候,提供了更好的访问父类的方式。

微信小程序自定义轮播图swiper dots默认样式

23 | 01 | 2017

默认的swiper面板指示点都是小圆点黑灰的wx-swiper-dot::before,但这满足不了广大小伙伴需求,目前只尝试成功更改了外层wx-swiper-dot样式,效果如下。

784465-20161109124805905-264881914

对样式文件即*.wxss文件做如下修改 :

但是依然满足不了需求,需求是自己写的(给自己挖了个坑 T_T)然后上网各种查,就有了下文解决办法

首先当然是要禁用掉(直接删掉)swiper属性indicator-dots,再用view组件模拟dots,对应的代码如下:

然后是wxss代码:

再对swiper的bindchange属性绑定对应的事件:

20170112161516126

下一页