npm init
npm install —save express
创建.gitignore 存放 node_modules .DS_Store
var express = require(‘express’);
var app = express();
app.set(‘port’, process.env.PORT || 3000);
app.get(‘/‘, function(req, res){
res.type(text/plain)
res.status(200);
res.render(‘index’, {})
})
//定制404页面
app.use(function(req, res){
res.type(‘text/plain’);
res.status(404);
res.send(‘404 - Not Found’);
})
//定制500页面
app.use(function(err, req, res, next){
console.error(err.stack);
res.type(‘text/plain’);
res.status(500);
res.send(‘500 - Server Error’);
})
app.listen(app.get(‘port’, function(){
console.log(‘Express started onhttp://localhost:'+
app.get(‘port’);
})
handlebars 视图引擎
var app = express();
var handlebars = require(‘express3-handlebars’)
.create({defaultLayout: ‘main’});//默认布局
app.engine(‘handlebars’, handlebars.engine);
app.set(‘view engine’, ‘handlebars’);
创建views > layouts布局目录
视图引擎会默认返回text/html的内容类型和200状态码
static中间件可以将一个或多个目录指派为包含静态资源的目录,可以不经过处理直接发送到客户端。
如图片、CSS文件、客户端javascript等
创建对外开放的public目录
app.use(express.static(__dirname + ‘/public’));
给所有静态文件创建了路由 直接引用,忽略路径public
如:/img/logo.png
创建模块
var fortune = require(‘./lib/fortune.js’);
app.get(‘/about’, function(req, res) {
res.render(‘about’, { fortune: fortune.getFortune() });
})
请求体,get无请求主体内容
post请求常见媒体类型application/x-www-form-urlendcoded
文件类型multipart/form-data
ajax请求 application/json
req.query 查询字符参数
req.body post请求参数 req.body.name 必须引入中间件body-parser
req.route当前匹配路由信息
req.cookies/req.singnedCookies
req.headers
req.accepts([type])确定是否接受一个或一组指定的类型
req.ip 客户端IP地址
req.path 请求路径(不包含协议,主机,端口或查询字符串)
req.xhr 是否由Ajax发起
req.url
响应对象
res.status(code)
res.set(name, value) 设置响应头
res.cookie(name, value, [options]), res.clearCookie(name, [options])设置或清除客户端cookies值
res.redirect([status], url) 303
res.send(body) res.send(status, body)向服务器发送响应及可选的状态码
默认内容类型是text/html, 若修改需在res.send前 res.set(‘Content-Type’,’text/json’)
若body是对象或数组,响应将会以json形式发送(建议直接用res.json)
res.json(json) res.json(status, json)
res.jsonp(json) res.jsonp(status,json)
res.type(type)设置Content-Type 头信息
res.format(object)允许根据接收请求报头发送不同的内容
res.attachment([filename]) res.download(path, [filename], [callback])
res.sendFile(path, [option], [callback])
res.locals 对象,包含用于渲染视图默认上下文
res.render(view, callback) 配置模板引擎的渲染视图
app.post(‘/process-contact’, function(req, res) {
console.log(req.body.name);
console.log(req.body.email);
try {
//保存到数据库
return res.xhr ? res.render({success: true}) : res.redirect(303, ‘/thank-you’);
} catch(er) {
return res.xhr ? res.json({ error: ‘database error.’ }) : res.redirect(303, ‘/database-error’)
}
})
指定不同的模板或不使用布局
app.get(‘/foo’, function(req, res) {
res.render(‘foo’, {layout: null}) 或{layout: ‘microsite’}
}
局部文件
创建views/partials子目录,创建文件名称如weather, 于是上下文名称为partials.weather
在入口文件中,添加中间件
app.use(function(req, res, next) {
if(!res.locals.partials) res.locals.partials = {};
res.locals.partials.weather = getWeatherData(); //res.locals 定义上下文
}
在视图引擎中引用局部文件
{{ >weather}} 当partials中有子目录时,{{ >目录1/目录2 }}
经验:某个请求中要执行的中间件一定要在该get方法执行前调用!
模板引擎中遍历数组方法 及指定上下文环境
{{#each partials.weather.locations }}
{{/each}}
局部文件位置和局部文件上下文
段落
handlebars 实例化地section辅助方法
var handlebars = require(‘express3-handlebars’).create({
defaultLayout: ‘main’,
helpers: {
section: function(name, options){
if (!this._sections) this._sections = {};
this._sections[name] = options.fn(this);
return null;
}
}
})
Handlebars.compile 接收一个模板,返回方法,该方法接收一个上下文对象,返回已渲染的字符串
表单处理
默认为GET提交,在表单提交时需在form 中用 method=“POST”指定
action 被用于接收表单数据的url
带name属性的数据才能被服务器识别
表单提交时,默认编码是application/x-wwwform-urlencoded
发送文件使用multipart/form-data
处理表单的不同方式
浏览器提交和ajax
若表单使用POST请求,展现表单和处理表单通常使用相同的路径,一个是get方法,一个是post方法可以区分路径,
因而可以省略action。也可以用单独路径来处理表单
响应浏览器
直接响应HTML
303重定向
POST请求需要引入中间件来解析URL编码体
npm install —save body-parser
app.use(require(‘body-parser’)())
从而可以直接使用表单字段 如 req.body.name
$(document).ready(function(){
$(‘.newsletter’).on(‘submit’, function(event){
event.preventDefault();
var action = $(this).attr(‘action’);
var $container = $(this).closest(‘.forContainer’);
$.ajax({
url: action,
type: ‘POST’,
success: function(data) {
if(data.success) {
$container.html(‘
Thank you!
’)} else {
$container.html(’There was a problem’)
}
},
error: function(){
$container.html(‘There was a problem’)
}
})
}
})
应用程序
app.post(‘/process’, function(req, res) {
if(req.xhr || req.accepts(‘json,html’)===‘json’){ 询问最佳返回方式
res.send({success: true})
}else {
res.redirect(303, ‘/thank-you’) 重定向
}
})
文件上传
安装中间件 npm install —save formidable
指定类型 enctype=“multipart/form-data”
app.use(require('body-parser')());
app.use(express.static(__dirname + '/public’)); app.use(express.static('public'));