`
witcheryne
  • 浏览: 1100281 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

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

    博客分类:
  • node
阅读更多

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

 

  • 将所有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??

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

    • 大小: 260.5 KB
    • 大小: 11.1 KB
    • 大小: 12.1 KB
    0
    6
    分享到:
    评论
    6 楼 richmond.petbug 2015-02-06  
    在每一个路由请求回调中都要写一段判断文件是否存在,是否有更好的解决方案呢?
    5 楼 leo_luck 2014-06-10  
    请问一下
    访问的时候
    path.exists,一直返回不存在呢
    我log了一下filePath=blogs/first.md
    这是为什么呢
    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/
    3 楼 witcheryne 2012-09-12  
    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();
        }
      });
    })

    不知道这样做是否规范?


    Express 3.x 变化挺大的,  这篇教程估计要重写了...
    静态数据加载的问题我检查了一下.  现在Express默认采用router的方式, 资源定为估计是按照router路径进行的, 在app.js的configure中去掉router部分代码即可:

    // Configuration
    
    app.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
    2 楼 flovex 2012-09-08  
    改进:后面显示图像部分应该用下面的一句话就可以了
    res.sendfile(urlPath);
    1 楼 flovex 2012-09-08  
    我发现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();
        }
      });
    })

    不知道这样做是否规范?

    相关推荐

      Node.js-mongo-express-基于Web的MongoDB管理界面采用Node.js和express开发

      标题中的“Node.js-mongo-express-基于Web的MongoDB管理界面采用Node.js和express开发”揭示了我们讨论的主题:一个使用Node.js和Express框架构建的MongoDB Web管理界面,名为“mongo-express”。这个工具提供了图形...

      用node.js建博客(一) - node.js安装及Express框架简介

      在本教程中,我们将探索如何使用Node.js搭建一个博客系统,这是系列的第一部分,主要涉及Node.js的安装以及Express框架的基础知识。Node.js是一个开放源码、跨平台的JavaScript运行环境,它允许开发者在服务器端运行...

      新时期的node.js入门-李锴-书中示例代码

      书中还将涉及Express框架的使用,Express是Node.js中最流行的Web应用框架,它简化了路由设置、中间件使用和模板引擎等常见任务。通过Express,开发者可以快速搭建功能齐全的Web服务。 数据库连接也是Node.js开发中...

      学习node.js,搭建博客 共17章

      在本教程中,我们将深入探讨如何使用Node.js技术来搭建一个功能完备的博客系统。Node.js是一个基于Chrome V8引擎的JavaScript运行环境,以其非阻塞I/O模型和高效的事件驱动而闻名,非常适合构建高性能的网络应用,如...

      Node.js-Node.js-Express-MongoDB构建simpleblog

      在本项目中,我们主要探讨如何使用Node.js、Express框架以及MongoDB数据库来构建一个简单的博客系统,即"simple_blog"。这个项目是初学者掌握Web开发基础的绝佳实践,同时也适合那些希望深入理解Node.js全栈开发的...

      Node.js-Tiny-Express框架从需求到实现

      在本文中,我们将深入探讨如何使用Node.js构建一个微型的Express风格的Web开发框架,名为Tiny-Express。这个过程将涵盖从理解需求到实现的全过程,帮助你掌握Node.js核心特性以及如何构建自定义框架。 **一、Node....

      Node.js-Footing-使用Express和Node.js开发RESTAPI的基础

      **Node.js-Footing-使用Express和Node.js开发REST API的基础** 在现代Web开发中,REST(Representational State Transfer)API已经成为构建可扩展、模块化和跨平台应用的标准方式。Node.js,一个基于Chrome V8引擎...

      Node.js-node-express-by-hbs解决方案优化项目结构引用并重写基础依赖

      Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它让开发者能够在服务器端使用 JavaScript 进行编程。Express 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,它提供了一系列强大的特性,...

      node.js项目---编辑修改学生信息页面

      在本项目中,我们将使用Express.js,这是一个轻量级的Node.js web应用框架,它简化了HTTP服务器的创建和路由处理。 Express.js的核心在于其路由系统。通过定义不同的URL路径(或称为路由)及其对应的处理函数,我们...

      node.js+mysql博客全栈系统源码.zip

      node.js + express + mysql 包含前端博客展示、后台管理、node后端。整套博客系统开箱即用,对elemen-ui二次封装组件非常便利,管理端权限模块,用户登录,验证码,token验证,文章编辑,修改,查看,发布,评论,...

      用node.js建博客(三) - 用markdown写静态博客

      在本教程中,我们将深入探讨如何使用Node.js构建一个基于Markdown的静态博客系统。Node.js是一种流行的JavaScript运行环境,它允许我们在服务器端执行JavaScript代码,从而构建高效且可扩展的网络应用。Markdown则是...

      node-v14.15.5-x64 官方原版.zip

      标签“jsnode”表明这个压缩包与JavaScript和Node.js技术有关,可能包含有关如何使用JavaScript在Node.js环境中开发和运行代码的信息。 在压缩包内的文件“node-v14.15.5-x64.msi”是一个Windows Installer文件,...

      Node.js Web开发实战-(共14章)PPT.rar

      第1章 初识 Node.js.ppt 第2章 Javascript基础.ppt 第3章 Node.js基础入门.ppt 第4章 异步编程与包管理.ppt 第5章 http模块.ppt 第6章 Web开发中的模板引擎.ppt 第7章 Node.js中的文件操作.ppt 第8章 认识express...

      Node.js-EXPRESS初始化平台搭建

      Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它让JavaScript能够在服务器端执行,打破了JavaScript只能在浏览器端使用的限制。Node.js具有非阻塞I/O模型,使其在处理高并发场景时表现出色,常用于构建高...

      Node.js-vuenode实现的一个博客系统

      【标题】:“Node.js-vuenode实现的一个博客系统”揭示了这个项目是使用Node.js后端框架和Vue.js前端框架构建的一个完整的博客平台。Node.js是基于Chrome V8引擎的JavaScript运行环境,允许开发者在服务器端使用...

      Professional Node.js Building Javascript Based Scalable Software

      ### 专业Node.js:构建基于JavaScript的可扩展软件 #### 引言 随着网络应用程序的不断增长和发展,对高效、可扩展的技术栈需求也日益增加。Node.js作为一款基于Chrome V8引擎的JavaScript运行环境,提供了强大的...

    Global site tag (gtag.js) - Google Analytics