이번에는 Nodejs 라우팅 및 컨트롤러 사용법에 대해 소개해 드리겠습니다. Nodejs 라우팅 및 컨트롤러 사용 시 주의사항은 무엇인가요?
업무상 최근에 노드를 다시 배웠습니다. 마지막으로 노드를 배운 것은 2014년이었습니다. 순전히 개인적인 관심으로 기초를 배운 후에는 사용하지 않았고, 다른 프로젝트로 바빴습니다. 이번에 그냥 집어왔습니다. 더 이상 고민하지 않고 여기서 MEAN은 Mongodb, Express, Angular 및 Node를 나타냅니다. 프로젝트 전반에 걸쳐 단계별로 함께 진행됩니다. MEAN 스택의 가장 큰 특징은 어떤 프레임워크나 타사가 사용되는지가 아니라 프런트엔드와 백엔드 모두 동일한 언어, 즉 JavaScript를 사용한다는 점입니다. 초기에는 노드에 대해서도 회의적이었습니다. 이 페이지에서 DOM을 작동하는 데 사용되는 스크립팅 언어가 그렇게 많은 백엔드 모듈을 감당할 수 있을까? 그러나 그것이 의심스러웠을 때 나는 이 기사 시리즈를 쓰기로 결정하기 전에 그것에 대해 더 알아보기로 결정했습니다.
Mongodb는 데이터 저장에 사용되며 Express는 노드 기반 백엔드 프레임워크, Angular는 프런트엔드 프레임워크, Node는 백엔드 운영 환경입니다. 설치 과정과 노드 기능에 대해서는 다루지 않겠습니다. 온라인에 많은 것들이 있습니다. 개발환경은 VS2013 NTVS가 설치되어 있습니다. 노드를 설치한 후 환경 변수를 설정해야 하는 경우가 있습니다. cmd 디렉터리에 node -v를 입력합니다. 버전 번호가 표시되면 설치가 올바른 것입니다.
프로젝트 시작
VS에서 새 프로젝트를 만들고 JavaScript-->Node.js를 선택한 다음 Express4 애플리케이션을 선택하세요.
항상 Ctrl+C를 방지하려면 nodemon을 설치하고 파일을 업데이트하세요. -g는 전역적으로 설치한다는 뜻입니다.
npm install nodemon -g
routes 폴더 아래 index.js의 제목을 ReadingClub으로 수정하세요. 그런 다음 cmd를 사용하여 프로젝트 디렉터리로 전환하고 nodemon을 입력하여 프로젝트를 시작합니다.
브라우저에서 lochost:3000을 방문하여 성공적으로 엽니다.
먼저 Routes 폴더 아래의 index.js를 살펴보세요. 이는 간단한 경로이며 요청 방법입니다. get과 req는 요청을 나타내고, res는 응답을 나타냅니다.
render 메소드에는 렌더링할 뷰 템플릿의 이름을 나타내는 "index"라는 두 개의 매개변수가 있습니다. 여기서 기본 뷰 엔진은 jade이고 다음 {title:'ReadingClub'}은 전달되는 데이터 모델입니다. 보기에. 이는 Asp.net MVC의 반환 View()와 다소 유사하며 여기의 함수는 Asp.net MVC의 컨트롤러 작업과 동일합니다. View()의 기본값은 현재 작업 이름에 해당하는 보기입니다. 그리고 렌더링을 지정해야 합니다.
res는 응답을 직접 보낼 수도 있습니다.
res.send('respond with a resource');
Create Controllers
기본 라우팅 규칙이 있는 Asp.net MVC와 달리 Express 라우팅은 하나씩 구성해야 하므로 컨트롤러를 불러올 수도 있습니다. 하지만 그 전에 먼저 디렉터리를 수정해 보겠습니다. 다음과 같이 app_server 폴더를 생성합니다. 컨트롤러, 뷰, 경로로 구분됩니다. 원래 뷰와 경로를 직접 이동할 수 있습니다.
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' }); };
Routing
마찬가지로 view 폴더에 index.jade를 두 번 복사하고 books.jade와 about.jade로 변경합니다. 그런 다음 경로 아래의 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
首先看到很多的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错误页面。
요약: 이 섹션에서는 기본 요청 및 응답을 이해하기 위해 Express 프레임워크를 통해 기본 MVC 프로젝트를 설정하고 노드의 기본 모듈 및 미들웨어를 설정합니다. 전용 컨트롤러는 app.js의 관련 코드를 해석합니다. 다음 섹션에서는 모델과 뷰에 중점을 둡니다. 현재 node의 개발 환경은 매우 완성되어 있습니다. 이 기술은 2009년부터 현재까지 7년 동안 이미 많은 책과 자료가 나와 있으며, 국내 cnode 커뮤니티도 매우 활발합니다. 기술을 주식에 비유한다면 Java, C# 및 PHP는 의심할 여지 없이 시장에서 백마 주식입니다. 이러한 기술을 배우는 것은 위험이 낮으며 구직에 대해 걱정할 필요가 없습니다. Node는 마치 GEM 주식과도 같습니다. 큰 거품이 있고, 새로운 회사는 단지 투기적 개념일 뿐이라고 생각할 수도 있지만 빠르게 성장하고 있습니다.
이 기사의 사례를 읽은 후 방법을 마스터했다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요! RECEMEDRENDED 읽기 : nodejs 뷰 및 모델의 개발은 mongoose를 사용하여 모델과 aps
i
javaScript의 var, {} 및 functions를 생성합니다.
위 내용은 Nodejs 라우팅 및 컨트롤러 사용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!