用node.js建博客(四) - express中的404处理

上一篇中,我已经实现了如下管理功能,

 

将所有markdown文件(即:*.md文件),统一放到views/blogs目录下 将/blogs/*.html的url, 映射到markdown文件 在首页index.jade中,添加文章的链接

注意:

本片内容不太适合Express3.x, 建议参考附件中的 nodeblog_express3.x.zip Demo来看

 

 

 

本片介绍如何使用express为nodeblog带来404错误处理

实现功能

  1. 访问的链接存在的时候,显示页面
  2. 不存在,则显示404页面, 当然,这里的404是统一处理

 

技术准备:(2个)

1. Node.js中path模块的使用:

path模块提供一些处理文件路径的功能,采用require('path')来使用。这里我只使用到两个方法:

 

1). path.normalize(strPath)

将路径标准化, 如'/etc//hosts', 会被标准化成'/etc/hosts'

'/' 分隔符,如果在windows环境中会转换成'\'

 

2). path.exists(filePath, function(exists))

判断路径是否存在,true: 存在, false: 不存在,该方法还有个同步版: path.existsSync(filePath):boolean

2. Express中的路由控制:

1). 什么是路由?

例如下面代码可以截获 '/users/:id' url, 其中id是url参数 (REST-ful url! You are right!)

 

app.get('/users/:id', function  (req, res, next) {
    res.send('id:' + req.params.id)
    res.end();
}) 		

用 curl 看一下效果:

 

 

  2). 使用next做路由控制:

当一个url可以被多个路由匹配,则在response关闭前,调用next()进行路由跳转

 

app.get('/users/:id', function  (req, res, next) {
    console.log('id: ' + req.params.id);
    next();
})

app.get('/users/*', function  (req, res, next) {
    console.log('list all user');
    res.send('list all users \n');
})

  调用next()做路由跳转, 跳转规则按照app.get声明顺序执行。


 

开始为nodeblog添加404处理:(4步)

1. 调整app.js中的express配置

提高对 public/* 资源路由的优先级:

 

var express = require('express');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  
  // 将public提前
  app.use(express.static(__dirname + '/public'));
  app.use(app.router);
  // 以前在这里
  // app.use(express.static(__dirname + '/public'));
});

2. 修改对 '/blogs/:title.html' 的路由代码,

添加对文件是否存在的判断,这里需要先引入path模块: var path = require('path');

 

app.get('/blogs/:title.html', function(req, res, next) {
    
    var urlPath = [
        'blogs/',
        req.params.title, '.md'
    ].join('');
    
    var filePath = path.normalize('./' + urlPath);
    path.exists(filePath, function  (exists) {
        if(!exists) {
            next();
        } else {
            res.render(urlPath, {layout: false});
        }
    });

})

3. 添加404的处理:

app.get('*', function(req, res) {
    console.log('404 handler..')
    res.render('404', {
        status: 404,
        title: 'NodeBlog',
    });
})

   由于 '*' 也可以匹配 '/blogs/:title.html', 所以在 2 步骤中的next, 会将处理路由到这里。

 

4. 在views/ 下添加 404.jade 页面:

 

h1= title

img(src="/images/404.jpg")

 

5. app.js全部代码

 

require.paths.unshift('./mode_modules'); 
var express = require('express');
var markdown = require('markdown-js');
var path = require('path');

var app = module.exports = express.createServer();


// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  
  // pase form data to key-value paire
  app.use(express.bodyParser());
  // support put and delete HTTP Standar Method
  app.use(express.methodOverride());
  
  app.use(express.static(__dirname + '/public'));
  app.use(app.router);
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
});

app.register('.md', {
  compile: function(str, options) {
    var html = markdown.makeHtml(str);
    return function(locals){
      return html.replace(/\{([^}]+)\}/g, function(_, name){
        return locals[name];
      });
    };
  }
});

var config = {
    title: 'NodeBlog',
    author: 'lvjian'
}

// Routes

app.get('/', function(req, res){
  res.render('index', {
    title: config.title + ' - ' + config.author
  });
});

app.get('/markdown', function(req, res) {
    res.render('index.md', {layout: false});
})

app.get('/blogs/:title.html', function(req, res, next) {
    
    var urlPath = [
        'blogs/',
        req.params.title, '.md'
    ].join('');
    
    var filePath = path.normalize('./' + urlPath);
    path.exists(filePath, function  (exists) {
        if(!exists) {
            next();
        } else {
            res.render(urlPath, {layout: false});
        }
    });

})

app.get('*', function(req, res) {
    console.log('404 handler..')
    res.render('404', {
        status: 404,
        title: 'NodeBlog',
    });
})


app.listen(process.env.VMC_APP_PORT || 3000);  
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);

 

参考资料:

What next??

为程序引入单元测试,摆脱修改+刷新的工作方式.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值