搜索
首页web前端js教程Nodejs路由与控制器的使用

Nodejs路由与控制器的使用

Mar 16, 2018 pm 02:34 PM
javascriptnodejs控制器

这次给大家带来Nodejs路由与控制器的使用,Nodejs路由与控制器使用的注意事项有哪些,下面就是实战案例,一起来看一下。

因为工作需要,最近再次学习了node,上一次学习node是2014年,纯粹是个人兴趣,学了入门之后没有运用,加上赶别的项目又不了了之。这次正好捡起来。废话不多说,这里的MEAN指的是Mongodb、Express、Angular和Node。 通过整个项目逐步整合在一起。MEAN栈最大的特色不是运用了哪些框架或第三方,而是前后端都是一种语言,即JavaScript。早些年我也是对node抱着疑态度,觉得这个页面上操作dom的脚本语言,能扛得起后端那么多模块吗?但怀疑不防多了解一下,才决定写这个系列的文章。

Mongodb做数据存储,Express是基于node的后端框架,Angular是前端框架,Node是后端运行环境。安装过程和node的特性就不讲了,网上一大把。开发环境是VS2013.安装了NTVS。node安装完后,有时候需要设置下环境变量。在cmd目录下输入 node -v 如果显示版本号,则说明安装正确了。

起始工程

在VS中新建项目,选择JavaScript-->Node.js,选择Express4的应用。

  

  为了避免一直Ctrl+C,安装nodemon,文件更新,它会自动重启,-g表示安装成全局。

npm install nodemon -g

修改routes文件夹下的index.js中的title为ReadingClub。然后用cmd切到工程目录,输入nodemon启动工程。 

 在浏览器里面访问lochost:3000 ,成功打开:

 先看routes文件夹下面的index.js ,这就是一个简单的路由,处理的路径为“/”,请求方式get,req代表的是request,res代表的response。

 

render方法有两个参数,“index”,代表的是要渲染的视图模板名称,这里默认的视图引擎是jade,而后面{title:'ReadingClub'}就是传递到视图的数据模型。这里和Asp.net MVC 的return View() 有些相似,而这里的function就相当 Asp.net MVC中Controller的一个Action。View()默认是对应当前Action名称的视图。而render必须指定。

res 也可以直接发回一个响应

res.send('respond with a resource');

建立Controllers

 不像Asp.net MVC有默认的路由规则,Express的路由需要一个个配置,不妨把Controller提出来。但在此之前,我们先修改一下目录。如下,建立app_server文件夹。里面分controllers、views和routes。可以把原来的views和routes直接移进去。

在controllers文件夹中新建一个home.js,加入三个方法:index、books和about。

module.exports.index = function(req, res) {
    res.render('index', { title: 'Index' });
};module.exports.books = function(req, res) {
    res.render('books', { title: 'Books', });
};
module.exports.about = function (req, res) {
    res.render('about', { title: 'About' });
};

路由

同样,在view文件夹中把index.jade复制两遍,修改为books.jade和about.jade. 然后我们修改routes下的index.js,运用Express框架自带的Router。

var express = require('express');var router = express.Router();var homeController = require('../controllers/home');router.get('/', homeController.index);
router.get('/about', homeController.about);
router.get('/books', homeController.books);module.exports = router;

这时候还是无法运行的,因为我们改变了目录结构还没有在app.js中重新设定。首先设置路由:

var routes = require('./app_server/routes/index');
app.use('/', routes);

修改视图引擎的起始位置

//app.set('views', path.join(dirname, 'views'));app.set('views', path.join(dirname, 'app_server', 'views'));

dirname代表的是根目录。然后再浏览器访问/books或者/about 。

 这样就分离了controller,请求通过路由抵达控制器,控制器将模型数据填充到对应的视图的模板.这就是我们熟悉的MVC模式。我们再看router.METHOD方法定义。

router.METHOD(path, [callback, ...] callback)

这里的METHOD指get,post,put和delete等。因为我们可以定义:

router.get('/book/:bookId', homeController.detail);
router.put('/book/:bookId', homeController.updateBook);
router.delete('/book/:bookId', homeController.deleteBook);

虽然路径都是一样,但是代表的是不同的用意,完全restful,:bookId表示是参数。

同样支持正则匹配,会匹配类似于这样的‘GET /commits/71dbb9c’

router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){  var from = req.params[0];  var to = req.params[1] || 'HEAD';
  res.send('commit range ' + from + '..' + to);
});

如果每个请求都需要做某种处理,可以用all方法:

router.all('*', requireAuthentication, loadUser);

这等价于:

router.all('*', requireAuthentication)
router.all('*', loadUser);

Asp.net MVC的路由每一个都需要设置名称,且不能重复出现,且匹配到之后就不再匹配,Express没有这个限制,匹配到之后只要没返回响应就会向下继续传递。相对而言,Express的Router更灵活一些。

更多细节请参考官方API:http://www.expressjs.com.cn/4x/api.html#router

接下来我们回顾下整个app.js。

app.js

var express = require('express');var path = require('path');var favicon = require('serve-favicon');var logger = require('morgan');var cookieParser = require('cookie-parser');var bodyParser = require('body-parser');var routes = require('./app_server/routes/index');var app = express();// view engine setupapp.set('views', path.join(dirname, 'app_server', 'views'));
app.set('view engine', 'jade');// uncomment after placing your favicon in /public//app.use(favicon(dirname + '/public/favicon.ico'));app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(dirname, 'public')));
app.use(express.static(path.join(dirname, 'public')));
app.use('/', routes);// catch 404 and forward to error handlerapp.use(function (req, res, next) {    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});// error handlers// development error handler// will print stacktraceif (app.get('env') === 'development') {
    app.use(function (err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}// production error handler// no stacktraces leaked to userapp.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});
module.exports = app;

View Code

1.模块定义:

首先看到很多的require的语法。

var express = require('express');var path = require('path');var favicon = require('serve-favicon');var logger = require('morgan');var cookieParser = require('cookie-parser');var bodyParser = require('body-parser');var routes = require('./app_server/routes/index');

require表示应用一个模块,npm上已经有超过25万个包。这些能直接引用的模块,是已经安装在node_modules文件中。如果是自己定义的模块,比如routes 就要用相对路径。在node中模块分以下几类:

  • 核心模块,如http,fs,path等

  • .或..开始的相对路径文件模块

  • 以/开始的绝对路径文件模块

  • 非路径形式的文件模块,如自定义的模块。

核心模块会优先加载,以相对或绝对路径加载的模块,require都会转为真实路径,将编译执行后的结果放到缓存中,这样二次加载就会更快。require能加载.js,.node.json的文件,其余扩展名都会被当.js文件载入。模块与文件是一一对应的,一个文件夹的模块就称作包,包通常是一些模块的集合。require是用来获取模块,而exports对象就是用来定义模块。

module.exports.hello = function() {
console.log('Hello.');
};

相当于是定义接口,给外部调用。而上面的路由就是把一整个对象封装到模块中。

module.exports = router;

在app.js中直接获取到整个路由对象:

var routes = require('./app_server/routes/index');

看到module.exports直接赋值router有点奇怪,会想不会覆盖掉其他的模块吗,但事实上在编译的过程中,node会对获取的JavaScript文件内容进行包装,等于是每个文件之间都进行了作用域的隔离。

2.app.set

app.js中用set方法设置了路由起始路径和视图引擎。 

app.set('views', path.join(dirname, 'app_server', 'views'));//这里我们修改了路径在app_server文件夹下
app.set('view engine', 'jade');//默认的视图引擎是jade

还可以设置路由是否忽略大小写,默认是不忽略。

app.set('case sensitive routing',true)

还可以设置环境变量是开发环境还是生产环境,更多的设置可以参考官方文档:http://www.expressjs.com.cn/4x/api.html#app.settings.table

3.app.use

use方法是用来注册一系列中间件,监听端口上的请求,中间件利用了尾触发机制,每个中间件传递请求对象,响应对象和尾触发函数,通过队列形成一个处理流。

 最简单的中间件形式:

app.use(function (req, res, next) {
  console.log('Time: %d', Date.now());
  next();
})

看下各个中间件的作用:

app.use(logger('dev')); //日志,在开发环境下用彩色输出响应状态,会显示请求方式,响应时间和大小。
app.use(bodyParser.json());//解析json请求。
app.use(bodyParser.urlencoded({ extended: false }));//解析form请求(含有key-value键值对),false表示value的类型是string或array,为true表示任意类型。
app.use(cookieParser());//解析cookie
app.use(require('stylus').middleware(path.join(dirname, 'public')));//使用stylus做css预编译,并指定路径。
app.use(express.static(path.join(dirname, 'public')));//静态文件路径

4.error

我们看到在设置了路由之后,如果请求还没返回则认为页面没有找到,这个时候app抛出一个error。并继续往下传递

app.use('/', routes);// catch 404 and forward to error handlerapp.use(function (req, res, next) {    var err = new Error('Not Found');
    err.status = 404;    next(err);
});

而接下来,对错误进行了处理

// 开发环境错误处理// 会打印出错误堆栈if (app.get('env') === 'development') {
    app.use(function (err, req, res, next) {
        res.status(err.status || 500);//如果不是404就认为是内部错误
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}// 生产环境错误处理// no stacktraces leaked to userapp.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

检测到异常的时候,就渲染error模板。 接下来看下error模板,简单介绍下jade语法:

extends layout  //相当于Asp.net MVC 设置Layout
block content //相当于 Asp.net MVC RenderBody
  h1= message  //显示message
  h2= error.status  //显示错误状态
  pre #{error.stack} //错误堆栈

这样就能处理404和500错误页面。

小结:至此,整个默认工程已经介绍完,这一节通过Express框架建立一个基本的MVC工程,了解基本的请求和响应,node的基本模块和中间件;并初步设置了路由,建立起专门的controller;解读了app.js中的相关代码;下一节关注模型和视图。时至今日,node的开发环境已经很完善,从09年到现在这个技术已经走过了7年了,已经有很多书籍资料,国内的cnode社区很活跃。如果把技术比喻成股票的话,java,C#,PHP这些无疑是大盘白马股,学这样的技术风险小,不愁找不到工作。而node这样的就像创业板股票,你也许认为这有很大的泡沫,认为新的公司不过是炒概念,但他就是在快速增长着。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Nodejs视图与模型的开发

Nodejs使用Mongoose创建模型及AP

JavaScript的var与this,{}与function

以上是Nodejs路由与控制器的使用的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JavaScript在行动中:现实世界中的示例和项目JavaScript在行动中:现实世界中的示例和项目Apr 19, 2025 am 12:13 AM

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

了解JavaScript引擎:实施详细信息了解JavaScript引擎:实施详细信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python vs. JavaScript:学习曲线和易用性Python vs. JavaScript:学习曲线和易用性Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python vs. JavaScript:社区,图书馆和资源Python vs. JavaScript:社区,图书馆和资源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C到JavaScript:所有工作方式从C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器