在学习koa的过程中,遇到了一个比较坑的地方,我以为是koa的bug,还给koa提了个issue,然后有个朋友给了个能解决问题的方法,我试了下,确实报错解决了,但是方法太粗暴。后来还是通过看koa源码和nodejs的http模块,找到了问题所在。
废话不多说,“Talk is cheap, show me the code”.
const Koa = require("koa")
const app = new Koa()
const [port, host] = ["8082", "0.0.0.0"]
app.use(async (ctx, next) => {
ctx.body = "hello world"
// 当把ctx.message设置为中文或者其他语言,例如日语的时候,会抛出
// TypeError [ERR_INVALID_CHAR]: Invalid character in statusMessage这个错误
ctx.message = "随便一串中文"
await next()
});
// 格式化返回数据,对这个问题没有影响
app.use(async (ctx, next) => {
ctx.body = {
code: 0,
data: ctx.body,
msg: ctx.message
}
await next()
})
app.listen(port, host, () => {
console.log(`APP server running on http://${host}:${port}`);
})
当把ctx.message设置为中文或者其他语言,例如日语的时候,服务会报错,并且这个错误通过app.on('error')也是捕捉不到的,然后浏览器会提示'500 Internal Server Error'。什么原因呢?
koa源码
在response.js中:
可以看到,当设置
ctx.message = '随便一串中文'时,调用的是
set message(msg) {
this.res.statusMessage = msg;
}
那么res.statusMessage是啥?
在application.js中:
可以看到,
res.statusMessage实际上是nodejs的response对象的response.statusMessage,那这个是干嘛的呢?statusMessage其实是http状态码的一部分,我查了下http协议的RFC2616,这个东西叫做Reason Phrase,是对http状态码描述,给人看的。至于为什么不能设置为中文或其他语言,我没找到原因,应该涉及到协议底层编码的问题,我不懂这个!
总结
遇到问题,多找资料(^o^)/~