This time I will bring you the use of Nodejs routing and controllers. What are the precautions when using Nodejs routing and controllers? The following is a practical case, let’s take a look.
Due to work needs, I recently learned node again. The last time I learned node was in 2014. It was purely a personal interest. After learning the basics, I didn’t use it, and I was busy with other projects. Just picked it up this time. Without further ado, MEAN here refers to Mongodb, Express, Angular and Node. Comes together step by step throughout the project. The biggest feature of the MEAN stack is not which frameworks or third parties are used, but that both the front and back ends use the same language, namely JavaScript. In the early years, I was also skeptical about node. I thought that the scripting language used to operate DOM on this page could afford so many back-end modules? But when I doubted it, I decided to learn more about it before deciding to write this series of articles.
Mongodb is used for data storage, Express is a back-end framework based on node, Angular is a front-end framework, and Node is a back-end running environment. I won’t go into the installation process and node features, there are a lot of them online. The development environment is VS2013. NTVS is installed. After node is installed, you sometimes need to set environment variables. Enter node -v in the cmd directory. If the version number is displayed, it means the installation is correct.
Start Project
Create a new project in VS, select JavaScript-->Node.js, and select the Express4 application.
In order to avoid Ctrl+C all the time, install nodemon and update the file. It will automatically restart. -g means to install it globally.
npm install nodemon -g
Modify the title in index.js under the routes folder to ReadingClub. Then use cmd to switch to the project directory and enter nodemon to start the project.
Access lochost:3000 in the browser and successfully open:
First look at the index under the routes folder .js, this is a simple route, the processing path is "/", the request method is get, req represents the request, and res represents the response.
The render method has two parameters, "index", which represents the name of the view template to be rendered. The default view engine here is jade, and the following {title:' ReadingClub'} is the data model passed to the view. This is somewhat similar to Asp.net MVC's return View(), and the function here is equivalent to an Action of the Controller in Asp.net MVC. View() defaults to the view corresponding to the current Action name. And render must be specified.
res You can also directly send back a response
res.send('respond with a resource');
Establish Controllers
Unlike Asp.net MVC which has default routing rules, Express routing needs to be configured one by one, so you might as well Bring up the Controller. But before that, let's modify the directory first. As follows, create the app_server folder. It is divided into controllers, views and routes. You can move the original views and routes directly into it.
Create a new home.js in the controllers folder and add three methods: index, books, and 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' }); };
Routing
Similarly, copy index.jade twice in the view folder and modify it to books.jade and about.jade. Then we modify index.js under routes and use The Router that comes with the Express framework.
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;
It still cannot run at this time because we have changed the directory structure and have not reset it in app.js. First set the routing:
var routes = require('./app_server/routes/index'); app.use('/', routes);
Modify the starting position of the view engine
//app.set('views', path.join(dirname, 'views'));app.set('views', path.join(dirname, 'app_server', 'views'));
dirname represents the root directory. Then access /books or /about in the browser.
这样就分离了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
首先看到很多的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文件内容进行包装,等于是每个文件之间都进行了作用域的隔离。
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
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')));//静态文件路径
我们看到在设置了路由之后,如果请求还没返回则认为页面没有找到,这个时候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错误页面。
Summary: So far, the entire default project has been introduced. This section uses the Express framework to build a basic MVC project to understand basic requests and responses, node’s basic modules and middleware; and initially set up routing and established Special controller; Interpretation of the relevant code in app.js; The next section focuses on models and views. Today, the development environment of node is very complete. This technology has been used for 7 years from 2009 to now. There are already many books and materials, and the domestic cnode community is very active. If you compare technology to stocks, Java, C#, and PHP are undoubtedly white horse stocks in the market. Learning such technologies has low risk and you don't have to worry about finding a job. Node is like GEM stocks. You may think that there is a big bubble, and that new companies are just speculative concepts, but they are growing rapidly.
I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the php Chinese website!
Recommended reading:
Development of Nodejs views and models
Nodejs uses Mongoose to create models and API
JavaScript’s var and this, {} and function
The above is the detailed content of The use of Nodejs routing and controllers. For more information, please follow other related articles on the PHP Chinese website!