在Node.js中实现Express(1)

    Express提供了一个轻量级模块,把Node.js的http模块功能封装在一个简单易用的接口中。Express也扩展了http模块的功能,使你轻松处理服务器的路由,响应,cookie和HTTP请求的状态。本篇文章章介绍如何在Node.js应用程序中实现Express充当Web服务器。你将学习如何配置Express服务器,设计路由,并利用Request和Response对象发送和接收HTTP请求。你也将了解如何在Express中实现模板引擎。

1,Express入门

    在Node.js的项目中开始使用Express是非常简单的。所有你需要做的就是添加express模块,在项目的根目录下使用下面的命令来完成:

npm install express

    你还可以添加express到你的package.json模块,以确保当你部署应用程序时,express已安装。

    一旦你安装了express模块,就需要为你的Node.js应用程序创建一个express类的实例作为HTTP服务器。下面的代码行导入express模块,并创建你可以使用的express实例:

var express = require('express');
var app = express();
    1.1,配置Express设置

    Express提供了控制Express服务器的行为的一些应用程序设置。这些设置定义了环境以及Express如何处理JSON解析,路由和视图。下表列出了可以在Express对象中定义的设置。

Express应用程序的设置
设置 说明
env 定义环境模式字符串,如development(开发),testing(测试)和production(生产)。默认值是process.env.NODE_ENV
trust proxy 启用/禁用反向代理的支持。默认设置为disabled(禁用)
jsonp callback name 定义JSON请求的默认回调名称。默认值是?callback=
json replacer 定义JSONreplacer回调函数。默认为null
json spaces 指定当格式化JSON响应时使用的空格数量。默认值在开发中是2,在生产中是0
case sensitive routing 启用/禁用区分大小写。例如, /home与/Home是不一样的,默认为disabled
strict routing 启用/禁用 严格的路由。例如,/home与/home/是不一样的。默认设置为disabled
view cache 启用/禁用视图模板编译缓存,这保留编译模板的缓存版本。默认设置为enabled(启用)
view engine 指定呈现模板时,如果从视图中省略了文件扩展名,应该使用的默认模板引擎扩展
views 指定模板引擎用来查找视图模板的路径。默认值是./views

    express对象提供set(setting,value),enable(setting)和disable(setting)方法来为应用程序的设置来设定值。例如,下面代码启用信任代理设置,并设置视图引擎(view engine)为jade:

app.enable('trust proxy');
app.disable('strict routing');
app.set('view engine','jade');

    为了得到一个设定的值,使用get(setting),enable(setting)和disabled(setting)方法。例如:

app.enabled('trust proxy');  \\true
app.disabled('strict routing');  \\true
app.get('view engine');   \\jade

  1.2,启动Express服务器

    为了把Express实现为Node.js应用程序的服务器,你需要创建一个实例,并开始监听一个端口。下面的3行代码就启动了一个非常基本的监听端口8080的Express服务器:

var express = require('express');
var app = express();
app.listen(8080);

    该app.listen(port)调用把底层的HTTP连接到port(端口)上,并开始监听它。底层的HTTP连接使用的是利用在http库中创建的Server对象上的listen()方法产生的相同连接。

    事实上,express()返回的值实际上是一个回调函数,它映射了传递到http.createServer()和https.createServer()方法的回调函数。

    下面的代码清单显示了如何使用Node.js实现一个基本的HTTP和HTTPs服务器。

var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();
var options = {
	host:'127.0.0.1',
	key:fs.readFileSync('ssl/server.key'),
	cert:fs.readFileSync('ssl/server.crt')
};
http.createServer(app).listen(80);
https.createServer(options,app).listen(443);
app.get('/',function(req,res){
	res.send('Hello from Express');
});

2,配置路由

    前面讲了如何启动Express HTTP服务器。然而,在服务器可以开始接受请求前,你需要先定义路由。路由(route)是一个简单的定义,它描述如何处理针对Express服务器的HTTP请求的URL路径部分。

    2.1 实现路由

    你可以把路由定义为两部分。第一部分是HTTP请求方法(通常是GET或POST)。路由定义的第二部分是在URL中指定的路径,例如,/用于一个网站的根目录,/login用于登录页面,而/cart用于显示购物车。这些方法常常需要进行完全不同的处理。

    express模块提供了一系列的函数,可让你在Express服务器中实现路由。这些函数都使用以下语法:

app.<method>{path,[callback...],callback}

    语法的<method>部分指的是HTTP请求方法,如GET或POST。例如:

app.get(path,[middleware,...],callback)
app.post(path,[middleware,...],callback)

    path指的是要通过回调函数来处理的URL的路径部分。middleware参数是回调函数执行前要应用的中间件函数。callback参数是应该处理该请求并把响应发回客户端的请求处理程序。callback参数应该接受Request对象作为第一个参数并接收Response对象作为第二个参数。

    例如,下面的示例实现了一些基本的GET和POST路由:

var express = require('express');
var http = require('http');
var app = express();
http.createServer(app).listen(80);
app.get('/',function(req,res){
	res.send("Server root");
});
app.get('/login',function(req,res){
	res.send("login page");
});
app.post('/save',function(req,res){
	res.send("Save page");
});

    当Express服务器接收到一个HTTP请求时,它会查找已经为适当的HTTP方法和路径的定义的路由。如果找到一个,那么Request和Response对象被创建来管理请求,并被传递给路由的回调函数。

    Express还提供了app.all()方法,它的工作效果与app.get()和app.post()方法完全一样。唯一的区别在于,回调函数app.all()调用用于指定路径的每个请求,而不管是否是HTTP方法。此外,app.all()方法可以接受*字符作为路径的通配符。这对于实现记录请求日志或其他特殊的功能来处理请求是一个很棒的特性。例如:

app.all('*',function(req,res){
	//全部路径的全局处理程序
});
app.all('/user/*',function(req,res){
	// /user路径的全局处理程序
});
    2.2,在路由中应用参数

    当你开始实现路由时,你很快就会看到,对于复杂系统,路由数量会多得不可收拾。为了减少路由数量,可以在URL中实现参数。你可以使用参数,通过为不同的请求提供唯一值来定义应用程序如何处理请求并生成响应,从而为类似的请求使用相同的路由。

    例如,你不会对系统中的每个用户或产品拥有不同的路由。相反,你会把一个用户ID或产品ID作为参数传递到一个路由,而服务器代码将使用该ID来确定要使用哪个用户或产品。实现路由参数主要有4种方法。

  • 查询字符串:你可以在URL的路径后面使用标志的?key=value&key=value...HTTP查询字符串,这是用于实现参数的最常用的方法,但这些URL会变得非常冗长和费解。
  • POST参数:当实现一个Web表单或另一个POST请求时,可以在请求正文中传递参数。
  • 正则:你可以定义一个正则表达式作为路由的路径部分。Express使用正则表达式来解析
  • 定义的参数:你可以在路由的路径部分使用:<parm_name>按名称定义一个参数。当解析路径时,Express自动为该参数分配一个名称。

    以下各节讨论除post参数外的所有这些方法。

    使用查询字符串应用路由参数

    将参数添加到路径的最简单方法是使用普通的HTTP查询字符串格式?key=value&key=value...来传递它们,然后使用url.parse()方法来解析Request对象的url属性来获得参数。

    下面的代码实现到/find?author=<author>&title=<title>的基本GET路由,它接受author(作者)和title(标题)参数。当要真正获得作者和标题的值时,用url.parse()方法创建一个查询对象:

var express = require('express');
var url = require('url');
var http = require('http');
var app = express();
http.createServer(app).listen(80);
app.get('/find',function(req,res){
	var url_parts = url.parse(req.url,true);
	var query = url_parts.query;
	res.send('Finding Book:Author: ' + query.author + 'Title:' + query.title);
});

运行结果:


    使用正则表达式应用路由参数

    在路由中实现参数的一种很棒的方法是使用正则表达式来匹配模式。使用正则表达式可以让你为路径实现不遵循标准的/格式的模式。

    下面的代码实现了一个正则表达式的解析器,它为位于URL:/book/<chapter>:<page>的GET请求生成路由参数:

app.get(/^\/book\/(\w+)\:(\w+)?$/,function(req,res){
	res.send('Get Book:Chapter: ' + req.params[0] + 'page: '+req.params[1]);
});

    使用已定义的参数来应用路由参数

    如果你有更加结构化的数据,那么不要使用正则表达式,你可以使用已定义的参数。使用已定义的参数,可以在路由的路径中按名称定义参数。你使用<param_name>定义路由的路径参数。当使用定义的参数时,req.param是一个函数,而不是一个数组,而调用req.param(param_name)返回参数的值。

    下面的代码实现了一个基本的:userid参数,这需要一个格式为/user/<user_id>的URL:

app.get('user/:userid',function(req,res){
	res.send("Get User: "+req.param("userid"));
});

    为已定义的参数应用回调函数

    使用已定义的参数的一个主要好处是,如果定义的参数在URL中,你可以指定被执行的回调函数。当解析URL时,如果Express发现某个参数有注册的回调函数,它就在调用路由处理程序之前调用参数的回调函数。你可以为一个路由注册多个回调函数。

    要注册一个回调函数,可以使用app.param()方法。app.param()方法接受已定义的参数作为第一个参数,然后是一个接收Request,Response,next和value参数的回调函数:

app.param(param,function(req,res,next,value){});

    Request和Response对象与传递给路由回调函数的对象是相同的。next参数是一个用于已注册的下一个app.param()回调的回调函数(如果有的话)。你必须在回调函数中的某处调用next():

app.param('userid',function(req,res,next,value){
	console.log("Resquest with userid: " + value);
	next();
});

    应用路由参数示例:

var express = require("express");
var url = require('url');
var app = express();
app.listen(80);
app.get('/',function(req,res){
	res.send("Get Index");
});
app.get('/find',function(req,res){
	var url_parts = url.parse(req.url,true);
	var query = url_parts.query;
	var response = 'Find Book:Author:'+query.quthor + 'Title: '+query.title;
	console.log('\nQuery URL: '+req.originalUrl);
	console.log(response);
	res.send(response);
});
app.get(/^\/book\/(\w+)\:(\w+)?$/,function(req,res){
	var response = 'Get Book:Chapter: '+ req.params[0] + 
	'page: '+req.params[1];
	console.log('\nRegex URL:'+req.originalUrl);
	console.log(response);
	res.send(response);
});
app.get('/user/:userid',function(req,res){
	var response = 'Get User: '+req.param('userid');
	console.log('\nParam URL:' + req.originalUrl);
	console.log(response);
	res.send(response);
});
app.param('userid',function(req,res,next,value){
	console.log("\nRequest received with userid: "+value);
	next();
});

    3,使用Request对象

    你将一个Request对象作为第一个参数传递到路由处理程序。Request对象提供请求的数据和元数据,包括URL,标头,查询字符串,等等。它可以让你在代码中正确地处理请求。

    下表列出了Request对象可用的最常用的一些属性和方法。

HTTP Request对象的属性和方法
属性或方法 说明
originalUrl 请求的原始URL字符串
protocol 协议的字符串,例如http或https
ip 请求的ip地址
path 请求URL的路径部分
host 请求的主机名
method HTTP方法:GET,POST等
query 请求的URL的查询字符串部分
fresh 一个布尔值,当最后修改与当前匹配时为true
stale 一个布尔值,当最后修改与当前匹配时为false
secure 一个布尔值,当建立TLS连接时为true
acceptsCharset(charset) 一个方法,如果由charset指定的字符集受支持,则返回true
get(header) 返回header的值的方法
headers 请求标头的对象形式

    下面的代码清单显示了如何访问Request对象的各个部分。

var express = require('express');
var http = require("http")
var app = express();
http.createServer(app).listen(80);
app.get('/user/:userid',function(req,res){
	res.send("URL:\t " + req.originalUrl+"protocol:\n " +
	req.protocol+"IP:\n"+req.ip+"Path:\t" + req.path+"Host:\n" + 
	req.host+"Method:\n" + req.method+"Query:\n" + 
	JSON.stringify(req.query)+"Fresh:\n" + 
	req.fresh+"Stale:\n" + req.stale+"Secure:\n" + 
	req.secure+"UTF8:\n" + req.acceptsCharset('utf8')+
	"Connection: " + req.get('connection')+"Headers:" 
	+ JSON.stringify(req.header,null,2)+"User Request");
});

4,使用Response对象

    传递到路由处理程序的Response对象提供了必要的功能来建立和发送适当的HTTP响应。以下各节讨论如何使用Response对象来设置标头,设置状态,并将数据发送回客户端。

    4.1,设置标头

    设置标头是制定适当的HTTP响应的一个重要组成部分。例如,设置Content-Type标头告诉浏览器是如何处理响应。Response对象提供了几个辅助方法来获取和设置所发送的HTTP响应的标头值。

    最常用的方法是get(header)和set(header,value),它们分别获取和设置任何标头值。例如,下面的代码首先获取Content-Type标头,然后将其设置:

var oldType = res.get('Content-Type');
res.set('Content-Type','text/plain');

下表说明获取和设置标头值的辅助方法。

在Response对象上获取和设置标头值的方法
方法 说明
get(header) 返回所指定的header参数的值
set(header,value) 设置header参数的值
set(headerObj) 接受一个对象,它包含多个'header':'value'属性。每个在headerObj参数中的标头都在Response对象中被设置
location(path) 把location标头设置为指定的path参数。该路径可用是URL路径,例如/login:完整的URL,如http://server.net/;相对路径,如../users;或者是一个浏览器行为,如back
type(type_string) 根据type_string参数设置Content-Type标头。该type_string参数可以是一个正常的内容类型,如application/json;部分类型,如png;或文件扩展名,如html
attachment([filepath])

把Content-Disposition标头设置为attachment,并且如果指定filepath,则Content-Type头是基于文件扩展名设置的

    4.2,设置状态

    如果响应的HTTP状态是200以外的值,那么你需要设置它。发送正确的状态响应,从而使浏览器或其他应用程序可以正确地处理HTTP响应是很重要的。要设置状态响应,应使用status(number)方法,其中number参数是在HTTP规范中定义的HTTP响应状态。

    例如,下面的行设置不同的状态:

    res.status(200); //OK正确

    res.status(300); //Redirection 重定向

    4.3,发送响应

    在本章前面一些发送简单的响应的例子中,你已经看到了send()方法的实际用法。send()方法可以使用下列格式,其中status是HTTP状态代码而body是一个String或Buffer对象:

res.send(status,[body])
res.send([body])

    如果指定Buffer对象,则内容类型被自动设置为application/octet-stream(应用程序/八位字节流);除非你明确地将其设置为别的东西。例如:

res.set('Content-type','text/html');
res.send(new Buffer('<html><body>HTML String</body></html>'));

    只要你为响应设置适当的标头和状态,send9)方法就可以真正处理所有的必要响应。一旦send()方法完成,它就设置res.finished和res.headerSent属性值。你可以使用这些来验证该响应是否被发送,传输了多少数据等。

    下表的清单说明了一些设置状态和标头,以及发送响应的基础知识。

var express = require('express');
var url = require('url');
var app = express();
app.listen(80);
app.get('/',function(req,res){
	var response = '<html><head><title>Simple Send</title></head>' + 
	'<body><h1>hello world</h1></body></html>';
	res.status(200);
	res.set({
		'Content-Type':'text/html',
		'Content-Length':response.length
	});
	res.send(response);
	console.log('Response Finished? ' + res.finished);
	console.log('\nHeaders Sent: ');
	console.log(res.headerSent);
});
app.get('/error',function(req,res){
	res.status(400);
	res.send("This is a bad resquest.");
});
    4.4,发送JSON响应

    使用JSON数据从服务器传输信息到客户端,然后让客户端动态填充页面上的HTML元素,而不是让服务器构建HTML文件或HTML文件的一部分,并把HTML发送到客户端,这是一个日益增长的趋势。Express 在Response对象上提供了json()和jsonp()方法,它们可以方便而漂亮地发送JSON。这些方法都采用类似send()的语法,但正文是一个JSON字符串化的JavaScript对象:

res.json(status,[object])
res.json([body])
res.jsonp(status,[object])
res.jsonp([object])

    JavaScript对象被转换为JSON字符串,并发送回客户端。在jsonp()的情况下,请求对象的URL包括?callback=<method>参数;而JSON字符串被包装在与方法同名的函数中,它可以在浏览器客户端被调用来支持JSONP设计。

    下面清单实现了json()和jsonp()来说明发送json数据到服务器。

var express = require('express');
var url = require('url');
var app = express();
var http = require('http');
app.listen(80);
app.get('/json',function(req,res){
	app.set('json spaces',4);
	res.json({name:"Smithsonian",built:'1846',item:'137m',
		centers:['art','astrophysics','natural history',
		'planetary','biology','space','zoo']});
});
app.get('/error',function(req,res){
	res.json(500,{status:false,message:"Internal Server Error"});
});
app.get('/jsonp',function(req,res){
	app.set('jsonp callback name','cb');
	res.jsonp({name:"Smithsonian",built:'1846',item:'137m',
		centers:['art','astrophysics','natural history',
		'planetary','biology','space','zoo']});
});



    4.5,发送文件

    在Express中有一个出色的辅助方法,即Response对象上的sendfile(filepath)方法。sendfile()使用一个函数调用来完成将文件发送到客户端需要做的全部事情。具体来说,sendfile()方法执行以下操作:

  • 基于文件扩展名设置Content-Type标头的类型
  • 设置其他标头,如Content-Length(内容长度)
  • 设置响应的状态
  • 使用Response对象内部的连接,把文件的内容发送呆客户端。

    sendfile()方法使用一下语法:

res.sendfile(path,[options],[callback])

    path应指向你要发送给客户端的文件。options参数是一个对象,它包含了一个maxAge属性定义的最长期限的内容和root属性(它是一个用来支持path参数相对路径的根路径)。当文件传输完成时,回调函数被调用,并接受一个错误作为唯一的参数。

    下面的代码清单显示了使用sendfile()命令发送一个文件。

var express = require('express');
var url = require('url');
var app = express();
app.listen(80);
app.get('/image',function(req,res){
	res.sendfile('2.jpg',
	{maxAge:1,//24*60*60*1000,
	root:'./views/'},
	function(err){
		if(err){
			console.log('err');
		}else{
			console.log('success');
		}
	});
});

结果:


    4.6,发送下载响应

    Express包括res.download()方法,该方法的工作原理非常类似于res.sendfile()方法,只有少数差异。res.download()方法把文件作为HTTP响应的附件发送,这意味着Content-Disposition(内容设置)标头是已设置的。res.download()方法采用以下语法:

res.download(path,[filename],[callback])

    path参数指向发送到客户端的文件。filename参数可以指定一个应该在Content-Disposition标头中发送的不同的文件名。回调函数在文件下载完成后执行。

    4.7,重定向响应

    当你实现一个web服务器时,你可能需要把来自客户端的请求重定向到在同一台服务器上的一个不同位置,或完全不同的服务器上。res.redirect(path)方法负责处理重定向到一个新位置的请求。

    下面的清单说明了你可以使用的各种重定向地址。

var express = require('express');
var url = require('url');
var app = express();
app.listen(80);
app.get('/google',function(req,res){
	res.redirect('http://www.baidu.com');
});
app.get('/first',function(req,res){
	res.redirect('/second');
});
app.get('/second',function(req,res){
	res.send("Response from Second");
});
app.get('/level/A',function(req,res){
	res.redirect("../B");
});
app.get('/level/B',function(req,res){
	res.send("Response from Level B");
});

5,实现一个模板引擎

    一个日益增长的趋势是,使用模板文件和应用程序数据,借助模板引擎来生成HTML;而不是从头开始构建HTML文件,或者使用静态文件。模板引擎基于应用程序提供的值,使用template对象创建HTML。使用模板引擎提供了如下好处

  • 简单:模板尽量做到容易生成HTML,要么用速记符号,要么允许把JavaScript直接嵌入在HTML文档中。
  • 速度:模板引擎优化构建HTML文档的过程。很多进程编译一个模板并把编译后的版本存储在用于加快HTML响应生成速度的缓存中

    以下各节讨论在Express中实现模板引擎。存在一些可用于Express的模板引擎。下面介绍两种模板引擎:jade和内嵌的JavaScript(EJS)。两个模板引擎中,jade使用HTML的速记符号模板,所以它的模板文件看上去并不像HTML。而EJS使用特殊的符号在正常的HTML文档中嵌入JavaScript。这使得它更容易从正常的HTML过渡。其不足之处是HTML文档比原始文档要复杂的多,不如jade模板整洁。

    安装jade和ejs如下:

npm install jade
npm install ejs
5.1,定义一个模板引擎

    实现模板引擎的第一步是为Express应用程序定义一个默认的模板引擎。你可以通过在express()应用程序对象上对viw engine设定进行设置来做到这一点。你还需要吧views设定为你的模板文件将被存放的位置。例如,下面的代码把./views目录设置为模板文件的根并把jade作为视图引擎:

var app = express();
app.set('views','./views');
app.set('view engine','jade');

    然后,你需要为自己希望使用app.engine(ext,callback)方法来处理的模板扩展名注册模板引擎。ext参数是用于模板文件的文件扩展名,callback参数是支持Express的呈现功能的函数。

    许多引擎在一个__express函数中提供回调功能。例如:

app.engine('jade',require('jade').__express)

    不过,如果你想为HTML扩展名注册EJS,就需要使用:

app.engine('html',require('ejs').renderFile)

    一旦扩展名被注册,引擎回调函数被调用来呈现具有该扩展名的模板。如果你选择除jade和ejs外的不同引擎,则需要弄清楚他们期望如何用Express来注册。

5.2,加入本地对象

    在呈现一个模板时,你可能需要包括动态数据,例如,为刚从数据库中读取的用户数据呈现一个页面。在这种情况下,你可以生成一个locals对象,它包含映射到模板中定义的变量名称的属性。express() app对象提供了app.locals属性来存储本地变量。app.locals实际上是一个函数对象,这意味着你可以用两种不同的方式来设置变量。

    要直接指定本地模板变量,可以使用点语法。例如,下面的代码定义本地变量title和version:

app.locels.title = 'my App';
app.locals.version = 10;

    你也可以通过调用app.locals(object)设置本地模板变量,其中object是一个JavaScript对象,它具有要设置的变量。例如:

app.locals({title:'My App',version:10});
5.3,创建模板

    在呈现一个模板时,你需要创建模板文件。在创建模板文件时,请记住以下注意事项。

  • 可重用性:尽量让模板可在应用程序的其他部分和其他应用程序中重复使用。大多数模板引擎都通过缓存模板来加速性能。模板越多,引擎就要花费越多的缓存时间。努力组织你的模板,以便它们可以用于多种用途。例如,如果你在一个应用程序中有显示数据的几个表,那就为所有的表制作一个不仅可以动态地添加数据,还能设置列头和表头等的单独模板。
  • 规模:由于模板的规模不断增长,因此它们往往会变得越来越臃肿。尽量将你的模板根据它们表示的数据分门别类。举例来说,如果你有一个具有菜单栏,窗体和表格的模板,就可以把它分割成3个独立的模板。
  • 层次:大多数网站和应用程序都按照某种层次建立,例如<head>部分以及横幅和菜单可以在整个站点相同。你应该对出现在多个位置的组件使用一个单独的模板,并在建立你的最后一页时只包括这些子模板。

    下面的清单显示应用一组局部变量在列表中显示用户信息

user_ejs.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>EJS Template</title>
</head>
<body>
	<h1>User using EJS Template</h1>
	<ul>
		<li>Name:<%=uname %></li>
		<li>Vehicle:<%=vehicle%></li>
		<li>Terrain:<%=terrain%></li>
		<li>Climate:<%=climate%></li>
		<li>Location:<%=location%></li>
	</ul>
</body>
</html>

    下面的清单显示了如何使用jade来实现一个主模板,然后在一个子模板中使用它。

                                main_jade.jade:一个简单的jade模板,定义了一个主网页

doctype html
html(lang="en")
	head
		title="Jade Template"
	body
		block content

            user_jade.jade:一个简单的jade模板,它包含了main_jade.jade模板,并增加了用于显示用户的元素

extends main_jade
block content
	h1 User Jade Template
	ul
		li Name: #{uname}
		li Vehicle: #{vehicle}
		li Terrain: #{terrain}
		li Climate: #{climate}
		li Location: #{location}
5.4,在响应中呈现模板

    一旦你定义和配置了一个模板引擎,并创建了模板,就可以使用Express app对象或使用Response对象发送一个呈现后的模板。要呈现在Express app对象中的模板,你可以使用app.render()方法,如下所示:

    app.render(view,[locals],callback)

    view参数指定views目录中的视图文件名。如果该文件没有包含扩展名,就尝试默认的扩展名,如.jade和.ejs。locals参数允许你传递一个locals对象(如果没有在app.locals中定义这样一个locals对象)。回调函数在模板中被呈现后执行,并应该接受错误对象作为第一个参数,并以呈现后的模板的字符串形式作为第二个参数。

    要直接把模板呈现为一个响应,则可以使用res.render()函数,它的工作原理与app.render()完全一样,不同之处是不必有回调函数。所呈现的结果在响应中自动发送。

    app.render()和res.render()方法均运行良好。如果你不需要在发送之前对数据任何处理,就可以使用res.render()方法,以免你需要额外的代码调用res.send()来发送数据。

    可以看一个下面的清单:

var express = require('express');
var jade = require('jade');
var ejs = require('ejs');
var app = express();
app.set('views','./views');
app.set('view engine','jade');
app.engine('jade',jade.__express);
app.engine('html',ejs.renderFile);
app.listen(80);
app.locals = {
	uname:'Brad',
	vehicle:'Jeep',
	terrain:'Mountains',
	climate:'Desert',
	location:'unkown',
};
app.get('/jade',function(req,res){
	res.render('user_jade');
});
app.get('/ejs',function(req,res){
	app.render('user_ejs.html',function(err,renderedData){
		res.send(renderedData);
	});
});

运行结果:


在Node.js中实现Express(2) :  https://blog.csdn.net/qq_39263663/article/details/80498260

猜你喜欢

转载自blog.csdn.net/qq_39263663/article/details/80480990