Express blog从零开始搭建(2)

来源:互联网 发布:网络作者亘古传奇 编辑:程序博客网 时间:2024/06/02 03:03

package.json


{    ...    "scripts": {        "start": "node ./bin/www   // 指定执行脚本    },    "dependencies": {        "body-parser": ...,             "cookie-parser": ...,           "debug": ...,                   "ejs": ...,                     "express": ...,                 "morgan": ...,                  "serve-favicon": ...        }}

body-parser: express中间件,作用是对post请求的请求体进行解析。
cookie-parser: express中间件,解析cookies
debug: 仿照nodejs核心调试技术的一个小型JavaScript调试工具。
ejs: 视图模板渲染引擎
express: nodejs web应用程序框架
morgan: nodejs http请求日志中间件
serve-favicon: nodejs 提供favicon的中间件

app.js


  • 设置视图模板渲染引擎
// 指定渲染引擎目录app.set('views', path.join(__dirname, 'views');// 指定渲染引擎app.set('view engine', 'ejs');

回溯: Express blog从零开始搭建(1)中使用express -v -e .命令时,app.js中指定渲染引擎的代码为app.set('view engine', '-e'),并不是我们期望的ejs视图模板引擎,因为当使用-v参数时不能使用ejs的简写指令-e

  • 使用morgan打印日志
app.use(logger('dev'));

实现终端打印日志, dev参数,可以看morgan的源码:

/** * dev (colored) */morgan.format('dev', function developmentFormatLine (tokens, req, res) {  // get the status code if response written  var status = headersSent(res)    ? res.statusCode    : undefined  // get status color  var color = status >= 500 ? 31 // red    : status >= 400 ? 33 // yellow    : status >= 300 ? 36 // cyan    : status >= 200 ? 32 // green    : 0 // no color  // get colored function  var fn = developmentFormatLine[color]  if (!fn) {    // compile    fn = developmentFormatLine[color] = compile('\x1b[0m:method :url \x1b[' +      color + 'm:status \x1b[0m:response-time ms - :res[content-length]\x1b[0m')  }  return fn(tokens, req, res)})

这里注释说明是以高亮的形式在终端输出日志。这里如果不确定dev参数的用处,可以去掉,即直接使用app.use(logger()),然后就会在控制台获得如下报错信息:

morgan deprecated undefined format: specify a format app.js:19:9morgan deprecated default format: use combined format app.js:19:9

使用express-generate生成的express项目中使用到的中间件或依赖包,还是需要做了解的。在不关心细节的情况下,可以根据上面抛出的异常去查看源码支持的几种format。

function morgan(format, options) {    ...    return function logger(req, res, next) {        ....    }}

morgan最后返回的是一个命名为logger的中间件。

  • 使用body-parser解析post请求的请求体
app.use(bodyParser.json());     // 加载解析json的中间件app.use(bodyParser.urlencoded({ extended: false })); // 加载解析urlencoded的中间件

bodyParser.json()解析json格式的数据
bodyParser.urlencoded()解析form表单提交的数据,也就是请求头中包含: Content-Type: application/x-www-form-urlencoded

回顾一下Content-Type的四种类型:
1. application/x-www-form-urlencoded 常见的表单提交
2. multipart/form-data 文件提交
3. application/json json格式数据
4. text/xml xml格式数据

  • 加载解析cookie的中间件
app.use(cookieParser());
  • 设置public为静态资源存放的目录
app.use(express.static(path.join(__dirname, 'public')));
  • 路由
app.use('/', index);app.use('/users', users);
  • 捕获404并转发到错误处理程序
app.use(function(req, res, next)) {    var err = new Error('Not Found');    error.status = 404;    // 转发到错误处理程序    next(err);}

因为没有做特殊的处理,JavaScript的Error对象的所有公共属性都会暴露。

  • 错误处理程序
app.use(function(err, req, res, next) {    // 设置locals,只在开发环境中呈现错误信息    res.locals.message = err.message;    // 设置locals错误信息    res.locals.error = req.app.get('env') === 'development' ? err : {};     // 设置locals的error对象为error    // 渲染错误页面    res.status(err.status || 500);    // 填充res的状态码,程序未处理的返回500    res.render('error');      // express/lib/response.js [res.render = function render(view, options, callback)]});

与error页面呈现的信息对应一下:

<h1><%= message %></h1>         // 错误信息<h2><%= error.status %></h2>    // 错误状态码<pre><%= error.stack %></pre>   // 错误堆栈信息,这里是具体的错误信息

res.render('error');点明将会渲染的视图,如果即将渲染的视图路由不存在时,则会调用内置的错误处理程序。
如果访问一个不存在的路由,内置的错误处理程序不会将路由重定向到某个路由,而是直接将错误信息打印在当前并不存在的路由页面中,使得看上去是当前访问的路由呈现的错误信息。
访问不存在的路由

module.exports = app; // 将app.js作为模块导出
  • 内置错误处理程序

Express内置的错误处理程序,负责处理应用程序中可能遇到的任何错误,这个内置的错误处理中间件函数添加在中间件函数集的末尾。

原因:
如果将错误传递给next()且未在自定义的错误处理程序中处理,则将由内置的错误处理程序处理;错误将写入客户端的堆栈跟踪内。堆栈跟踪并不存在于生产环境。
在生产环境中,如果在响应之后调用next()时出错,express的内置错误处理程序会关闭连接并使请求失败。因此在自定义错误处理程序时,如果响应头已经发送到客户端,要考虑委托给内置错误处理程序处理。

bin/www


  • 文件声明
#!/usr/bin/env node

声明是node可执行文件

  • 设置端口
var port = normalizePort(process.env.PORT || 3000);app.set('port', port);

如果设置了process.env.PORT,对其序列化并使用;否则使用默认端口3000。

  • 创建HTTP服务器
var server = http.createServer(app);
  • 监听端口
server.listen(port);
  • HTTP server的error和listening事件监听
server.on('error', onError);server.on('listening', onListening);
原创粉丝点击