首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

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

2012-12-23 
用node.js建博客(四) - express中的404处理在上一篇中,我已经实现了如下管理功能,?将所有markdown文件(即:

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

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

?

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

  • 注意:

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

    ?

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

    ?

    ?

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

    实现功能
      访问的链接存在的时候,显示页面不存在,则显示404页面, 当然,这里的404是统一处理

    用node.js筑博客(四) - express中的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 看一下效果:

    ?

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

    ?

    ?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声明顺序执行。


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

    ?

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

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

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

    ?

    var express = require('express');var app = module.exports = express.createServer();// Configurationapp.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= titleimg(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();// Configurationapp.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'}// Routesapp.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);

    ?

    参考资料:

    CNodeJS提供的Path API说明(中文)Express中文手册[实践经验+代码]用node.js和express.js和jade搭建轻型cms系统What next??

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

    // Configurationapp.configure(function(){ app.set('port', process.env.VMC_APP_PORT || 3000); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.use(express.favicon()); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride());// app.use(app.router); app.use(express.static(path.join(__dirname, 'public')));});

    新代码我已上传, module 我删掉了, 运行需要重新 npm install 4 楼 sqfasd 2012-10-20   flovex 写道我发现404 error中的图片是不能正常显示的,原因是没有添加图片解析的路由,后来在app.js中间加上这一段处理就好了:

    app.get('/images/:title.jpg',function(req,res) {
      console.log("Request image was called.");

      var urlPath = [
      // 获取相对路径, 我的应该是:  
      process.cwd(), 
      '/images/', 
      req.params.title, '.jpg' 
      ].join('');

      fs.readFile(urlPath, "binary", function(error, file) {
        if(error) {
          res.writeHead(500, {"Content-Type": "text/plain"});
          res.write(error + "\n");
          res.end();
        } else {
          res.writeHead(200, {"Content-Type": "image/jpg"});
          res.write(file, "binary");
          res.end();
        }
      });
    })

    不知道这样做是否规范?


    这段代码在windows下不能工作,
    首先文件分隔符需要转化下,用path.normalize
    其次,images的目录如果是放在public下,使用render函数会自动帮你查找到
    如果使用readFile或者sendfile,你要自己加上完整的路径,就是/public/images/

  • 热点排行
    Bad Request.