闲来无事把nodejs 升级到了 v6.10.0,然后遇到了一个非常奇怪的问题。
TypeError: The header content contains invalid characters
at storeHeader (_http_outgoing.js:318:11)
at ServerResponse.OutgoingMessage._storeHeader (_http_outgoing.js:228:9)
at ServerResponse.writeHead (_http_server.js:221:8)
WTF,这什么鬼?!
开始以为自己哪里写错代码来,但想来之前的版本都没错,应该不是我的问题。于是一边上google搜索,一边去查文档,翻各种论坛记录。
最后,还是在查阅了 nodejs 的源代码之后,才终于让我发现了错误的原因。
_http_outgoing.js 这个文件在 318 行调用了下面这个函数(位于_http_common.js 的 303-326 行 )。
function checkInvalidHeaderChar(val) {
val += ''; if (val.length < 1) return false; var c = val.charCodeAt(0); if ((c <= 31 && c !== 9) || c > 255 || c === 127) return true; if (val.length < 2) return false;
c = val.charCodeAt(1); if ((c <= 31 && c !== 9) || c > 255 || c === 127) return true; if (val.length < 3) return false;
c = val.charCodeAt(2); if ((c <= 31 && c !== 9) || c > 255 || c === 127) return true; /*
* 就是下面这个 for 循环造成的原因。
* 在添加非ASCII字符之后,这里会被 判断为非法字符而被 check 出来,
* 于是就在 _http_outgoing.js 的 318 行抛出 TypeError。
*/
for (var i = 3; i < val.length; ++i) {
c = val.charCodeAt(i); if ((c <= 31 && c !== 9) || c > 255 || c === 127) return true;
} return false;
}
然后现在我在 cookie 中插入了点中文之后,就华丽丽的浪费了快一个小时。
原因找到了,解决方案也就出来了——虽然比较挫。遇到符合以上标准的字符的时候,就直接转换成UNICODE
码。
但是,看到了这段代码,就还是想要问,为什么这里会加上这么一段检查呢?这个问题就留给下次解决吧。
好像StackOverflow 上似乎也有人问过,github上也有人提过类似的 issue,但因为全是英文就没去仔细看了,等着有机会再去看看。