《koa诞生记》——HTTP状态码

预计写的这十几篇文章是基于Koa initial commit版本,会逐渐对这几年来提交的1000多个Commit做个分析,目的是希望大家了解一个开源项目从诞生到成熟涉及的方方面面。

Koa源码中有许多堪称惊艳的代码片段,这里先举一个HTTP状态码的例子。

在上一篇文章中介绍了koa之实现,其中提出了在响应请求的过程中,如何正确的定义http状态码这个问题。

STATUS CODE

来看一下nodejsstatusCode的定义

  const STATUS_CODES: {
        [errorCode: number]: string | undefined;
        [errorCode: string]: string | undefined;
    };

从定义中看,STATUS_CODES是一个字面量, key的类型是 string | numbervalue类型是 string

它在nodejs标准库中,是这样的一个对象:

{ '100': 'Continue',
  '101': 'Switching Protocols',
  '102': 'Processing',
  '200': 'OK',
  '201': 'Created',
  '202': 'Accepted',
  '203': 'Non-Authoritative Information',
  '204': 'No Content',
  '205': 'Reset Content',
  '206': 'Partial Content',
  '207': 'Multi-Status',
  '208': 'Already Reported',
  '226': 'IM Used',
  '300': 'Multiple Choices',
  '301': 'Moved Permanently',
  '302': 'Found',
  '303': 'See Other',
  '304': 'Not Modified',
  '305': 'Use Proxy',
  '307': 'Temporary Redirect',
  '308': 'Permanent Redirect',
  '400': 'Bad Request',
  '401': 'Unauthorized',
  '402': 'Payment Required',
  '403': 'Forbidden',
  '404': 'Not Found',
…… 
}

题外话,nodejs实现 http模块其实是在 C++上封装了一层代码,具体的底层实现,可以看下这篇文章

Koa的实现

在Koa最初版本中,STATUS_CODE的作用是在 Context.js中的 status方法和 statusString方法。我们来看他们的作用。

  get statusString() {
    return http.STATUS_CODES[this.status];
  },
      
  set status(val) {
    if ('string' == typeof val) {
      var n = statuses[val];
      if (!n) throw new Error(statusError(val));
      val = n;
    }

    this.res.statusCode = val;
  }

从代码中可以看到, Koa希望Context类能够判断

  • 状态码是否存在
  • 实际意义与状态码的对应

这里主要是在 status方法中会对传入的 val值进行判断,如果传入的是字符串,则需要获取对应的 状态码。效果大概要达到status['Not Found'] == 404这样。这其实就是对象的 反向映射的处理。

来看Koa是如何实现的:

var http = require('http');
var codes = http.STATUS_CODES;

/**
 * Produce exports[STATUS] = CODE map.
 */

Object.keys(codes).forEach(function(code){
  var n = ~~code;
  var s = codes[n].toLowerCase();
  exports[s] = n;
});

在大多数在2013年使用js语言的人来讲,做一次简单反向映射的操作,可不是这三行语句。当然,对于现在的人来讲, 用类函数式写法可以一行了事。

话题跑远了, 这里的经典操作就是

  • 使用Object.keys来进行遍历并获取code值
  • 利用js的类型推导来将字符串转换成数字

当然,实际上还有一些人并不知道为什么js可以这样将字符串转换成数字(底层实现)。或者是不知道为什么 5取反会得 -6...

总结

对现在来看,这样的写法确实显得有些罗嗦。如果场景放在2013年,这样的操作还算能体现出扎实的基本功。

参考 & 引用

http的status_code

走进Node.js之HTTP实现分析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350