1.node的核心理念是事件驱动编程
2.路由:是指向客户端提供它所发出的请求内容的机制
3.__dirname常量会被解析为正在执行的脚本所在的目录
4.最基本node入口文件写法
var express = require(‘express’);
var app = express();
app.set(‘port’, process.env.PORT || 3000);
//引入sub模块
var sub = require(’./lib/sub.js’);
//设置handlebars试图引擎,并设置main.handlebars为默认模板
var handlebars =require(‘express3-handlebars’).create({defaultLayout:‘main’});
app.engine(‘handlebars’, handlebars.engine);
app.set(‘view engine’, ‘handlebars’);
//配置静态资源
app.use(express.static(__dirname+’/public’));
app.get(’/’, function(req, res){
//res.type(‘text/plain’);
//res.send(“home page”);
res.render(‘home’);
})
app.get(’/about’, function(req, res){
//res.type(‘text/plain’);
//res.send(“about page”);
res.render(‘about’,{subTitle: sub.getSub()});
})
//定制404页面
app.use(function(req, res){
//res.type(‘text/plain’);
res.status(404);
//res.send(‘error 404’);
res.render(‘404’);
})
//定制500页面
app.use(function(req, res){
//res.type(‘text/plain’);
res.status(500);
//res.send(‘error 500’);
res.render(‘500’);
})
app.listen(app.get(‘port’), function(){
console.log(“server start”);
})
*public为静态资源文件存放目录;views目录存放试图,views/layouts目录存放模板
5.bdd:行为驱动开发;tdd:测试驱动开发;CI:持续开发(node中最流行的CI服务器是Travis CI)
6.request.body(存储post请求参数):处理request对象body属性的时候需要引入中间件body-parser
引入方式:app.use(require(‘body-parser’)());request.query(存储get请求参数串);
7.注释:{{!注释内容}},这种注释方式优势是在客户端看不到注释内容
8.块级表达式
例子:
数据结构:{
subTitle: sub.getSub(),
mainTitle: ['title1', 'title2'],
ifHasSub: true
}
{{#each mainTitle}}
<h1>{{.}}</h1>
{{#if ../ifHasSub}}
<h2>{{../../subTitle}}</h2>
{{/if}}
{{/each}}
unless辅助方法跟if相反,当表达式为false时执行
9.先渲染视图后渲染布局
10.若想在指定视图不想使用布局,res.render(‘page’,{layout: null});若想使用不同布局模板,res.render(‘page’,{
layout: ‘otherTemplate’});
11.局部文件:放在views/partials目录下,{{> partial_name}}方式引入到视图
12.段落:
入口文件配置
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;
}
}
});
视图
{{#each mainTitle}}
<h1>{{.}}</h1>
{{#if ../ifHasSub}}
<h2>{{../../subTitle}}</h2>
{{/if}}
{{/each}}
{{#section 'jquery'}}
<script>
$(function(){
console.log("section");
})
</script>
{{/section}}
布局
<!doctype html>
<html>
<head>
<title>handlebars</title>
</head>
<body>
<header>
<img src="/img/1.jpg" />
</header>
{{{body}}}
<script src="/vendor/jquery-1.12.3.js"></script>
{{{_sections.jquery}}}
</body>
</html>
使用formidable中间件上传文件
安装formidable npm install formidable --save-dev
引入模块 var formidable =require('formidable');
处理表单 app.post('/upload', function(req, res){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files){
console.log('fields:'+fields);
console.log('files:'+files);
res.redirect(303, '/success');
})
})
14.cookie管理
凭证的外化
新建文件(credentials.js)
module.exports = {
cookieSecret: '123456'
}
通过require方式引入凭证
安装cookie-parser中间件 npm install cookie-parser --save-dev
引入中间件 app.use(require('cookie-parser')(credentials.cookieSecret))
设置cookie res.cookie(key, value, [{配置项}]);
取cookie req.cookies.cookieName
删除cookie res.clearCookie(key)
15.session管理
安装express-session npm install express-session --save-dev
引入session中间件 app.use(require('express-session')()); *必须在cookie后面引入
存取session都是通过req对象的session属性,删除session用delete 例子: delete req.session.sessionName;
16.中间件概念:是一种功能的封装方式,具体来说就是封装在程序中处理http请求的功能;一般有3个参数,req、res、next函数;如果在中间件里不调用next函数,则请求停止;(4个参数的时候第一个参数为错误对象)
16.邮件概念: MSA邮件提交代理 MTA邮件传输代理
安装nodemailer npm install nodemailer --save-dev
引入nodemailer并创建实例
var nodeMailer = require('nodemailer');
var mailTransport = nodeMailer.createTransport('SMTP', {
service: 'Hotmail',
secureConnection: false,
auth: {
user: credentials.mail.user,
pass: credentials.mail.password
}
});
发送邮件
mailTransport.sendMail({
from: '897839393@qq.com',
to: 'zhengchj@neusoft.com',
subject: 'node mail',
text: 'node mail test'
}, function(err){
if(err)
console.log('send mail error:' +err);
else
res.redirect('/success');
});
17.应用集群
app_cluster.js
var cluster = require(‘cluster’);
function startWorker(){
var worker = cluster.fork();
console.log(“worker %d started”, worker.id);
}
if(cluster.isMaster){
require(‘os’).cpus().forEach(function(){
startWorker();
});
cluster.on(‘disconnect’, function(worker){
console.log(‘worker %d disconnect from cluster’, worker.id);
});
cluster.on(‘exit’, function(worker, code, signal){
console.log(‘worker %d died with exit code %d (%s)’, worker.id, code, signal);
startWorker();
});
}else{
require(’./app.js’)();
}
app.js 启动服务代码
function startServer(){
app.listen(app.get(‘port’), function(){
console.log(“server start”);
})
}
if(require.main===module){
startServer();
}else{
module.exports = startServer;
}
监控工作线程
app.use(function(req, res, next){
var cluster = require(‘cluster’);
if(cluster.isWorker)
console.log(‘worker %d received request’, cluster.worker.id);
next();
});
18.处理子域名
安装vhost npm install vhost --save-dev
创建子域名 var admin = express.Router();
app.use(vhost('admin.*', admin));
创建子域名路由 admin.get('/', function(req,res){})
19.路由参数
例子:
app.get(’/admin/:name’, function(req, res){
console.log(req.params.name)
res.type(‘text/plain’);
res.send(‘admin admin’);
})
请求url …/admin/zheng,console.log打印的是zheng;请求参数会存储到req.params里
20.模块中声明路由
例子:student.js
module.exports = function(app){
app.get('/student', function(req,res){
console.log('student');
res.type('text/plain');
res.send('student student');
})
}
之后通过 require(’./student.js’)(app);的方式引入
21.跨域资源共享
安装cors模块 npm install cors --save-dev
指定路径共享 app.use('/api', require('cors')());