环境
官方文档地址:
IEDA
第一种方式(直接安装):
npm install express
npm init(生成package.json文件) 一直按回车
npm install ejs
第二种方式(安装生成器):
安装express生成器
npm install express-generator -g
命令行 express -h
**这是命令行输出**
-h, --help output usage information
--version output the version number
-e, --ejs add ejs engine support
--pug add pug engine support
--hbs add handlebars engine support
-H, --hogan add hogan.js engine support
-v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
-c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
--git add .gitignore
-f, --force force on non-empty directory
-v 代表视图模板,默认jade(很难用)
-c 代表css(可选less/sass)
//hbs 就是handlebars
安装模板实例(可根据项目安装不同模板):
一种方式:
express . 不推荐
y
另一种指定模板
express -v hbs -c less
express -v ejs -c sass
最后:
npm install 安装依赖
入门demo(基于第一种安装方式)
项目结构
node_modules/ ---包依赖
router/ ---路由
index.js
user.js
views/ ---视图
index.ejs ---模板文件
testExpress.js ---入口
testExpress.js(默认其实是app.js)
"use strict";
var express = require('express');
var app = express();
/**router处理全部东西
* app.use(require('./router/index'));
* 处理以/开始的
* app.get(post,use,all,...)
*/
app.all('/',require('./router/index'));
app.all('/user',require('./router/user'));
app.listen(3000, function () {
console.log('服务器启动了');
});
index.js中添加操作
通过express的Router(),得到路由。Router 实例是一个完整的中间件和路由系统
router上基本的delete,post,get,put..等。都存在,内有三个参数
分别是:
req : 请求
resp : 响应方法
包含以下方法
|方法 |描述
res.download() |提示下载文件。
res.end() |终结响应处理流程。
res.json() |发送一个 JSON 格式的响应。
res.jsonp() |发送一个支持 JSONP 的 JSON 格式的响应。
res.redirect() |重定向请求。
res.render() |渲染视图模板。
res.send() |发送各种类型的响应。
res.sendFile |以八位字节流的形式发送文件。
res.sendStatus() |设置响应状态代码,并将其以字符串形式作为响应体的一部分发送。
next : 用于中间件处理数据
'use strict'
var express = require('express');
var router = module.exports = express.Router();
router.get('/',function (req,resp,next) {
// 可以通过next添加中间处理,比如权限之类
console.log('这是中间件1');
next();
},function (req,resp,next) {
var data ={id:23,name:'这是一个张三'};
// resp.send('我在处理/开始的');
//render表示到哪个视图
resp.render('index.ejs',{data:data});
});
// 也可以使用下面方式处理
router.get('/',function (req,resp,next) {
// 可以通过next添加中间处理,比如权限之类
console.log('这是中间件1');
next();
});
router.get('/',function (req,resp,next) {
var data ={id:23,name:'这是一个张三'};
// resp.send('我在处理/开始的');
//render表示到哪个视图
resp.render('index.ejs',{data:data});
});
index.ejs将携带数据处理
ejs模板本身语法和jsp一样,这里就不详细说明
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<% for(var i =0 ;i<10;i++){%>
ID : <%=data.id%><br/>
姓名 : <%=data.name%>
<%}%>
</body>
</html>
user.js
'use strict'
var express = require('express');
var router = module.exports = express.Router();
router.get('/user',function (req,resp) {
resp.send('我在处理user');
});
基于express生成器(第二种方式)
项目结构
node_modules/ ---包依赖
router/ ---路由
index.js
user.js
file.js
util/ ---工具类
cookie-session.js -- 会话session
views/ ---视图
index.hbs ---模板文件
error.hbs
file.hbs
form.hbs
layout.hbs
app.js ---入口
监视目录、替换node
npm install supervisor -g(g代表全局)
cmd 命令行 %appData% (npm默认目录)如下图
一旦更新js, Ctrl+s 自动更新
配置图(基于IDEA)
构成
中间件、路由、视图(模板引擎,在下章介绍)
项目结构
中间件与路由
app、express.Router()
use([path],cb)、all(path,cb)、get()、post()、……(支持8种请求方式)
callback([err]、req、resp、next)、next()
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 index = require('./routes/index');
var users = require('./routes/users');
var file = require('./routes/file');
var help = require('./routes/help');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());//处理body
app.use(bodyParser.urlencoded({ extended: false }));//处理编码
app.use(cookieParser());//处理cookie
app.use(require('less-middleware')(path.join(__dirname, 'public')));//处理less
app.use(express.static(path.join(__dirname, 'public')));//处理public的静态网页
//处理路由
app.use('/', index);
app.use('/users', users);
app.use('/file', file);
app.use('/help', help);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/** error handler
* 错误页:回调函数,需要四个参数
* @callback([err]、req、resp、next)、next()
* @path : 代表页面url
* 回调 : 四个参数
* @err:错误,req:请求,resp:返回
* @next:用处,可以在页面跳转之前,执行其他操作,比如添加插件
*/
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
Request 方法
params、query、body、 cookies、 path
app、method、hostname、ip、originalUrl
/** Request
* @req.params 配合router得到后面的匿名参数
* /:x(\\d+)/:y(\\w+) 后面是正则,实现动态参数
* @req.query 得到表单提交的数据 -- get处理方式
* @req.body 得到表单提交数据post
* @req.cookies 得到客户端发送的cookies
* @req.path 当前path,router.all()后第一个参数
* @req.app 当前的app
* @req.method 当前的请求方式
* @req.hostname 当前的主机名
* @req.ip 当前的ip
* @req.originalUrl 原始的url
*/
form.hbs
<form method="post">
账户: <input type="text" name="name" id=""><br>
密码: <input type="password" name="password"><br>
<button>发送</button>
</form>
在index.js中
在地址栏输入访问
// http://localhost:3000/1/abc
// 得到后面的匿名参数
router.get('/:x(\\d+)/:y(\\w+)', function (req, resp, next) {
console.error(req.params);//{ x: '1', y: 'abc' }
resp.send(req.params);
}
// 得到get请求参数和cookies
router.get('/', function (req, resp, next) {
console.error(req.query);//得到get请求参数
console.error(req.cookies);//得到cookies
console.error(req.path);// /
console.error(req.app);
console.error(req.method);// GET
console.error(req.hostname);// localhost
console.error(req.ip);// ::1
console.error(req.originalUrl);// /
resp.render('form',{title:'测试'});
}
// 得到post请求参数和cookies
router.post('/', function (req, resp, next) {
console.error(req.body);// 得到post请求参数
console.error(req.cookies);//得到cookies
console.error(req.path);// /
console.error(req.app);
console.error(req.method);// POST
console.error(req.hostname);// localhost
console.error(req.ip);// ::1
console.error(req.originalUrl);// /
}
Responset方法
send()、render()、json()、jsonp()、redirect()
type()、set()
/** Response
* @resp.send(data) 将数据发送到页面,也可以是html
* @resp.render('modules',data) 前一个参数是跳转view下的页面 后一个参数时携带的数据
* @resp.json({}) 发送json数据
* @resp.jsonp({}) 实现跨域请求
* @resp.redirect() 重定向
* @resp.type('类型') 默认text/html 可以设置为普通文本text/plain
* @resp.set(,) 如果编码错误可以使用
*/
在index.js中
// 如果要测试,记得注释多余的resp代码
router.get('/', function (req, resp, next) {
console.error(req.query);
resp.send({name: 'zhangsan'});
resp.json({name: 'zhangsansan'});
//hbs 语法后面会讲
resp.render('form',{data:'sanzhangsan'});
resp.redirect('index');
/* jsonp,然后将地址栏改为http://localhost:3000/?callback=xx,再次看页面效果。跨域处理方案
*/
resp.jsonp({name: 'zhangsansan'});
// 默认是text/html 需要以纯文本解析就设置type
resp.type('text/plain');
resp.send('<h1>Hello World</h1>');
//如果想要设置更多头
resp.set({
'Content-Type': 'text/plain',
'Content-Length': '123',
'ETag': '12345'
});
resp.send('<h1>Hello World</h1>');
});
cookie-session
npm install cookie-session -S
将cookie-session设置为工具类,首先新建util目录,然后新建cookie-session.js文件
在cookie-session.js文件
const KEYS =['QAQA','cbabc','lisi'];
/**
* cookie-session就是个函数
* 中必定配置的项目是keys(加密秘钥)
* cookie会话session
* 在浏览器Application cookies中查看
* session以base64储存,session.sig是session校验
* cookie会话session
* */
module.exports = exports = {
cookieSession : require('cookie-session')({
name: 'session',
keys: KEYS,
// Cookie Options
maxAge: 24 * 60 * 60 * 1000 // 24 hours
})
};
router/users.js中
var express = require('express');
var router = module.exports = express.Router();
var cookieSession = require('../util/cookie-session').cookieSession;
//代表文件下全部都要使用session
router.use(cookieSession);
/**
* 仅仅是一个文件要使用,就用下面注释的方法
* */
// router.all('/',cookieSession ,function (req, res) {
router.get('/',function (req, res) {
console.error(req.session);
res.send('<h1>得到session</h1>');
});
//设置session
router.get('/set',function (req, res) {
req.session.userId = 5;
req.session.userName = '张三';
res.send('<h1>设置session</h1>');
});
//删除session的userId
router.get('/del',function (req, res) {
delete req.session.userId;
// delete req.session.userName;
res.send('<h1>删除session</h1>');
});
//删除session的全部
router.get('/delall',function (req, res) {
req.session = null;
res.send('<h1>删除全部session</h1>');
});
如果需要将其配置在app以中间件使用,参考文档
文件上传
npm install connect-multipart -S
用法:
connect-multiparty({maxFieldsSize、maxFilesSize、encoding})
参数:
maxFieldsSize:所有文件何在一起的大小
maxFilesSize:一个文件最大大小(若为多文件上传)
encoding:文件的编码
在views\file.hbs中
<h1>{{title}}</h1>
<!--
文件上传必须是post,设置enctype="multipart/form-data"
-->
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="file"><br>
<button type="submit">提交</button>
</form>
routes\file.js中配置路由
var express = require('express');
var router = module.exports = express.Router();
// 仅仅做测试就不设置参数
var upload = require('connect-multiparty')();
var fs = require('fs');
/*
get 访问views\file.hbs,携带数据title
*/
router.get('/', function (req, res) {
console.error(req.path);
res.render('file',{title:'测试文件上传'});
});
/*
post 用于文件上传操作
*/
router.post('/', upload, function (req, res) {
// req.files 得到上传文件的临时文件名
console.error(req.files.file.path);
// 重定向,防止用户重复提交
res.redirect('file');
// 创建输入流
var readStream = fs.createReadStream(req.files.file.path);
var name = new Date().getTime();
//通过内置fs模块读入文件
var writeStream = fs.createWriteStream( __dirname +"/../public/images/"+name+".jpg");
readStream.pipe(writeStream);
// 注册异步事件
readStream.on('end', function () {
fs.unlinkSync(req.files.file.path);
});
});
vhost(‘host’)
npm install vhost 虚拟主机
同一台电脑上的不同ip/域名绑定不同的服务,类似与PhpStudy里面的站点域名管理,新增不同的ip地址。
var vhost = require('vhost');
/*虚拟主机 node一般配合Nginx使用。此处做了解
* http://127.0.0.2:3000/ 进行访问
* */
app.use(vhost('127.0.0.1',function (req,resp) {
resp.end('123123');
}));
app.use(vhost('127.0.0.2',function (req,resp) {
resp.end('aadasd');
}));