热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

在上一篇中,我已经实现了如下管理功能,将所有markdown文件(即:*.md文件),统一放到viewsblogs目录下将blogs*.h

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

 

将所有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();// 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 paireapp.use(express.bodyParser());// support put and delete HTTP Standar Methodapp.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??

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

转:https://my.oschina.net/abcijkxyz/blog/723651



推荐阅读
  • 本文讨论了在使用PHP cURL发送POST请求时,请求体在node.js中没有定义的问题。作者尝试了多种解决方案,但仍然无法解决该问题。同时提供了当前PHP代码示例。 ... [详细]
  • node.jsrequire和ES6导入导出的区别原 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 在加载一个第三方厂商的dll文件时,提示“找不到指定模块,加载失败”。由于缺乏必要的技术支持,百思不得期间。后来发现一个有用的工具 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 本文介绍了Python函数的定义与调用的方法,以及函数的作用,包括增强代码的可读性和重用性。文章详细解释了函数的定义与调用的语法和规则,以及函数的参数和返回值的用法。同时,还介绍了函数返回值的多种情况和多个值的返回方式。通过学习本文,读者可以更好地理解和使用Python函数,提高代码的可读性和重用性。 ... [详细]
  • express工程中的json调用方法
    本文介绍了在express工程中如何调用json数据,包括建立app.js文件、创建数据接口以及获取全部数据和typeid为1的数据的方法。 ... [详细]
  • java实现rstp格式转换使用ffmpeg实现linux命令第一步安装node.js和ffmpeg第二步搭建node.js启动websocket接收服务
    java实现rstp格式转换使用ffmpeg实现linux命令第一步安装node.js和ffmpeg第二步搭建node.js启动websocket接收服务第三步java实现 ... [详细]
  • Yii framwork 应用小窍门
    Yiiframework应用小窍门1.YiiFramework]如何获取当前controller的名称?下面语句就可以获取当前控制器的名称了!Php代码 ... [详细]
  • 本文介绍了Sencha Touch的学习使用心得,主要包括搭建项目框架的过程。作者强调了使用MVC模式的重要性,并提供了一个干净的引用示例。文章还介绍了Index.html页面的作用,以及如何通过链接样式表来改变全局风格。 ... [详细]
author-avatar
EvilMaknaeKYU
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有