环境: Nodejs v8.10.0
“handlebars”: “^4.1.2”,
项目:静态资源服务器
报错信息:
Administrator@PO5ZCZBM35GLZP9 MINGW64 ~/Desktop/test2/src
$ node static_server.js
Server is running at http://127.0.0.1:9527
The header content contains invalid characters
报错原因
- The header content contains invalid characters
- 顾名思义,在 setHeader() 时,写入的无效的字符
- 经过多次调试发现,
- 在 static_server.js 文件中,如果不调用 isFresh(stats, req, res) 这个函数,就不会报错,如果调用了就会报错
- 说明,问题在该函数里
- 而在 cache.js 中,有4个 setHeader,利用二分法原理,每次分别对半注释掉,然后再执行代码,利用排除法找出问题的根源
- 最后,发现问题在于,cache.js 中 22行,由于 stats.mtime 返回的是一个时间对象,而时间对象无法设置为 Response Headers
- 所以,这里应该将他转为字符串 stats.mtime.toUTCString()
总结
- 1.保证代码的正确性
- 以后每次写程序,都要一边写,一边执行,保证每次写入的新代码 是没有问题的。
- 从而保证,项目从最开始就是完美的,可执行没有报错的。
- 不要等到写了一大堆,然后才执行代码,这样的话,由于代码过于复杂,很难找出问题所在
- 2.利用 二分法原理,排查问题
- 假如现在有一个复杂的项目,出了问题,但是不知道导致问题的根源在哪里
- 可以利用 二分法原理,每次注释掉一半的代码,然后执行,看看代码是否会报错。
- 如果报错,则问题在没被注释的代码中;
- 如果没报错,则问题在被注释掉的代码中。
- 利用这种方法,找到出错的部分,然后继续向下拆分,(不断重复向下拆分… 直到找到问题为止) 这样就能快速的排查问题了。
- 再大的项目,也不用10次,即可找出问题所在。
贴源码
// static_server.js
const http = require('http');
const path = require('path');
const fs = require('fs');
const handlebars = require('handlebars');
const promisify = require('util').promisify;
const stat = promisify(fs.stat);
const readdir = promisify(fs.readdir);
const mime = require('./mime');
const compress = require('./compress');
const range = require('./range');
const config = require('./defaultConfig');
const isFresh = require('./cache'); // 引入 isFresh 方法
const tplPath = path.join(__dirname, './template.html');
const source = fs.readFileSync(tplPath);
const template = handlebars.compile(source.toString());
const server = http.createServer((req, res) => {
const filePath = path.join(config.root, req.url);
console.log('filePath',filePath);
// const filePath = path.resolve(config.root, req.url);
handle(req, res, filePath).catch(error=>console.log(error.message));
});
server.listen(config.port, config.hostname, ()=>{
console.log(`Server is running at http://${
config.hostname}:${
config.port}`);
})
async function handle (req, res, filePath) {
try {
const stats = await stat(filePath);