命令:
$ npm install -g express
$ npm install -g express-generator
命令:
$ express [options] [dir]
Options:
--version 输出版本号
-e, --ejs 添加对 ejs 模板引擎的支持
--pug 添加对 pug 模板引擎的支持
--hbs 添加对 handlebars 模板引擎的支持
-H, --hogan 添加对 hogan.js 模板引擎的支持
-v, --view <engine> 添加对视图引擎(view) <engine> 的支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认是 jade 模板引擎)
--no-view 创建不带视图引擎的项目
-c, --css <engine> 添加样式表引擎 <engine> 的支持 (less|stylus|compass|sass) (默认是普通的 css 文件)
--git 添加 .gitignore
-f, --force 强制在非空目录下创建
-h, --help 输出使用方法
创建了一个名为 app 的 Express 应用,并使用ejs模板引擎
$ express --view=ejs app
这时,你也可以看到在app文件夹下的文件结构;
bin: 启动目录 里面包含了一个启动文件 www 默认监听端口是 3000 (直接node www执行即可)
node_modules:依赖的模块包
public:存放静态资源
routes:路由操作
views:存放ejs模板引擎
app.js:主文件
package.json:项目描述文件
Express上手非常简单,首先新建一个项目目录,假定叫做express。
进入该目录,新建一个package.json文件,内容如下。
{
"name": "express",
"description": "express test app",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "4.x"
}
}
上面代码定义了项目的名称、描述、版本等,并且指定需要4.0版本以上的Express。
然后,就可以安装了。
$ npm install
执行上面的命令以后,在项目根目录下,新建一个启动文件,假定叫做index.js。
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.get('/',function(req,res){ //访问根路径时输出hello world
res.send(`<h1 style='color: blue'>hello world</h1>`);
});
app.listen(8080);
然后,运行上面的启动脚本。
$ node index
路由表示应用程序端点 (URI) 的定义以及响应客户端请求的方式。它包含一个请求方时(methods)、路径(path)和路由匹配时的函数(callback);
app.methods(path, callback);
app.get("/login",function(req,res){
res.send("heng... women");
})
此路径地址将与/login匹配
此路由路径将与acd和相匹配abcd
app.get('/ab?cd', function (req, res) {
res.send('ab?cd')
})
这条路线的路径将会匹配abcd,abbcd,abbbcd,等等。
app.get('/ab+cd', function (req, res) {
res.send('ab+cd')
})
这条路线的路径将会匹配abcd,abxcd,abRANDOMcd,ab123cd,等。
app.get('/ab*cd', function (req, res) {
res.send('ab*cd')
})
此路由路径将与/abe和相匹配/abcde。
app.get('/ab(cd)?e', function (req, res) {
res.send('ab(cd)?e')
})
此路由路径将匹配其中带有“ a”的任何内容。
app.get(/a/, function (req, res) {
res.send('/a/')
})
这条路线的路径将匹配butterfly和dragonfly,但不butterflyman,dragonflyman等。
app.get(/.*fly$/, function (req, res) {
res.send('/.*fly$/')
})
const express = require("express");
var app = express();
app.get("/",function(req,res){
res.send(`<h1>主页</h1>`);
});
app.get("/login",function(req,res){
res.send(“登录页面”);
});
app.get("/registe",function(req,res){
res.send(“注册页面”);
});
app.listen(8080);
输入http://127.0.0.1:8080/login和http://127.0.0.1:8080/registe都能进入不同路由。
路由参数被命名为URL段,用于捕获URL中在其位置处指定的值。捕获的值将填充到req.params
对象中,并将路径中指定的route参数的名称作为其各自的键。
Route path: /users/:userId/books/:bookId
Request URL: http://localhost:3000/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }
要使用路由参数定义路由,只需在路由路径中指定路由参数,如下所示。
app.get('/users/:userId/books/:bookId', function (req, res) {
res.send(req.params)
})
使用express.Router
该类创建模块化的,可安装的路由处理程序。一个Router
实例是一个完整的中间件和路由系统; 因此,它通常被称为“迷你应用程序”。
以下示例将路由器创建为模块,在其中加载中间件功能,定义一些路由,并将路由器模块安装在主应用程序的路径上。
birds.js
在app目录中创建一个名为以下内容的路由器文件:
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
res.send('About birds')
})
module.exports = router
然后,在应用程序中加载路由器模块:
var birds = require('./birds')
// ...
app.use('/birds', birds)
通过req.query可以获得用户发送的get请求,之后通过node操作将相应数据返回给用户。
如果发送的是:
http://localhost:8080/login?goods1=0001&goods2=0002
响应的话则通过:
req.query
他会获取到全部数据,或
req.query.goods1
req.query.goods2
实例:
const express = require("express");
var app = express();
app.get("/",function(req,res){
res.send("主页");
});
app.get("/login",function(req,res){
console.log(req.query);
res.send("登录路由,goods1为:"+req.query.goods1+"==> goods2为:"+req.query.goods2);
});
app.listen(8080);
设置解析body中间件
app.use(express.urlencoded())
获取body数据
req.body.username
实例
var express = require('express');
var app = express();
//解析post提交的数据
app.use(express.urlencoded())
//处理登陆请求
app.post('/login',async (req,res)=>{
//获取用户名和密码
let username = req.body.username
let password = req.body.password
})
module.exports = app;
从字面意思,我们可以了解到它大概就是做中间代理操作,事实也是如此;大多数情况下,中间件就是在做接收到请求和发送响应中间的一系列操作。事实上,express是一个路由和中间件的web框架,Express 应用程序基本上是一系列中间件函数的调用。
执行流程
1.浏览器发送请求
2.express接受请求
中间处理的过程
3.路由函数处理渲染(req,res)
4.res.render渲染
const express=require("express");
var app=express();
//匹配路由之前的操作
app.use(function(req,res,next){
console.log("访问之前");
next(); //进行下一步 不写就只允许到访问之前
});
app.get("/",function(req,res){
res.send("主页");
});
app.listen(8080);
路由级中间件和应用级中间件类似,只不过他需要绑定express.Router();
var router = express.Router()
const express = require("express");
var app = express();
var router=express.Router();
router.use("/",function(req,res,next){
console.log("匹配前");
next();
});
router.use("/user",function(req,res,next){
console.log("匹配地址:",req.originalUrl);
next();
},function(req,res){
res.send("用户登录");
});
app.use("/",router);
app.listen(8080);
顾名思义,它是指当我们匹配不到路由时所执行的操作。错误处理中间件和其他中间件基本一样,只不过其需要开发者提供4个自变量参数。
app.use((err, req, res, next) => {
res.sendStatus(err.httpStatusCode).json(err);
});
const express=require("express");
var app=express();
app.get("/",function(req,res,next){
const err=new Error('Not Found');
res.send("主页");
next(err);
});
app.use("/user",function(err,req,res,next){
console.log("用户登录");
next(err);
},function(req,res,next){
res.send("用户登录");
next();
});
app.use(function(req,res){
res.status(404).send("未找到指定页面");
});
app.listen(8080);
express.static
express.json
express.urlencoded
body-parser
、compression
,cookie-parser
、morgan
、response-time
、serve-static
、session
安装
cnpm install cookie-parser --save
引入
const cookieParser=require("cookie-parser");
设置中间件
app.use(cookieParser());
设置cookie
res.cookie("name",'zhangsan',{maxAge: 900000, httpOnly: true});
//res.cookie(名称,值,{配置信息})
关于设置cookie的参数说明:
实例:
const express=require("express");
const cookieParser=require("cookie-parser");
var app=express();
//设置中间件
app.use(cookieParser());
app.get("/",function(req,res){
res.send("首页");
});
//设置cookie
app.get("/set",function(req,res){
res.cookie("userName",'张三',{maxAge: 20000, httpOnly: true});
res.send("设置cookie成功");
});
//获取cookie
app.get("/get",function(req,res){
console.log(req.cookies.userName);
res.send("获取cookie成功,cookie为:"+ req.cookies.userName);
});
app.listen(8080);
session是另一种记录客户状态的机制,与cookie保存在客户端浏览器不同,session保存在服务器当中; 当客户端访问服务器时,服务器会生成一个session对象,对象中保存的是key:value值,同时服务器会将key传回给客户端的cookie当中;当用户第二次访问服务器时,就会把cookie当中的key传回到服务器中,最后服务器会吧value值返回给客户端。
因此上面的key则是全局唯一的标识,客户端和服务端依靠这个全局唯一的标识来访问会话信息数据。
安装express-session
cnpm install express-session --save
引入express-session模块
const session=require("express-session");
设置session
session(options);
实例:
const express=require("express");
const session=require("express-session");
var app=express();
//配置中间件
app.use(session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: ('name', 'value',{maxAge: 5*60*1000,secure: false})
}));
app.use('/login',function(req,res){
//设置session
req.session.userinfo='张三';
res.send("登陆成功!");
});
app.use('/',function(req,res){
//获取session
if(req.session.userinfo){
res.send("hello "+req.session.userinfo+",welcome");
}else{
res.send("未登陆");
}
});
app.listen(8080);
以下演示通过销毁session的方式来退出登录
const express=require("express");
const session=require("express-session");
var app=express();
//配置中间件
app.use(session({
secret: "keyboard cat",//加密字符串
resave: false,//强制保存session
saveUninitialized: true,//是否保存初始化的session
cookie: ('name', 'value',{ maxAge: 5*60*1000,
secure: false,
name: "seName",
resave: false})
}));
app.use('/login',function(req,res){
//设置session
req.session.userinfo='张三';
res.send("登陆成功!");
});
app.use('/loginOut',function(req,res){
//注销session
req.session.destroy(function(err){
res.send("退出登录!"+err);
});
});
app.use('/',function(req,res){
//获取session
if(req.session.userinfo){
res.send("hello "+req.session.userinfo+",welcome to index");
}else{
res.send("未登陆");
}
});
app.listen(8080);
文件下载非常简单,仅需通过res.download()执行即可,他可以写为3种形式:
res.download('/report-12345.pdf');
以下是一个对选择对应文件进行下载的实例:
<form action="http://localhost:8080/" method="post" enctype="application/x-www-form-urlencoded">
<input type="file" name="files" value="选择下载的文件"><br><br>
<input type="submit" value="下载">
</form>
const express=require("express");
const bodyParser=require("body-parser");
var app=express();
var jsonParser = bodyParser.json();
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.post('/',urlencodedParser,function(req,res){
res.download("./public/"+req.body.files,err=>{
if(err){
res.send("下载失败!");
}else{
console.log("下载成功!");
}
});
});
app.listen(8080);
再上传文件时,我们通常会使用到他。Multer用于处理multipart/form-data 类型的表单数据。首先我们先安装它:
cnpm install multer --save
<form action="http://localhost:8080/" method="post" enctype="multipart/form-data">
<input type="file" name="files" value="指定文件">
<br><br>
<input type="submit" value="上传">
</form>
const express=require("express");
const multer=require('multer');
//初始化上传对象
var upload=multer({dest:'./upload/'});
var fs = require('fs');
var app=express();
//post 上传处理
//如果上传单个文件,可调用upload.single('files') file对于<input type="files" name="files" id="file"> 的name
app.use("/",upload.single("files"),function(req,res){ //files为input type="file"的name值
var oldFile=req.file.destination+req.file.filename; //指定旧文件
var newFile=req.file.destination + req.file.originalname; //指定新文件
fs.rename(oldFile,newFile,function(err){
if(err){
res.send('上传失败!');
}else{
res.send('上传成功!');
}
});
});
app.listen(8080);
在这里我们可以指定单个文件上传到根目录的upload文件夹里。这里值得注意的是req.file会返回文件的基本信息:
fieldname: ***, //input type="file"的name值
originalname: ***, //用户计算机上的文件的名称
encoding: '***', //文件编码
mimetype: ***', //文件的 MIME 类型
destination: './***/', //保存路径
filename: ***, //保存在 destination 中的文件名
path: ***, //已上传文件的完整路径
size: ** //文件大小(字节单位)
在HTML找中input type="file"需要加上multiple来实现过滤,multiple不写参数则可以读取·所有文件。而在服务端上,我们需要将single()改为array(“name”,num);的形式来接收多个文件的上传请求。最后对他们全部进行重命名。在这之前我们首先看看multer支持哪些文件上传方式:
.single(fieldname) //接受一个以 fieldname 命名的文件。.fields(fields)
.array(fieldname[, maxCount]) //接受一个以 fieldname 命名的文件数组。可以配置 maxCount 来限制上传的最大数量。
.fields(fields) //接受指定 fields 的混合文件。fields是一个拥有name和maxCount的数组对象。
.none() //只接受文本域。如果任何文件上传到这个模式,将发生 "LIMIT_UNEXPECTED_FILE" 错误。
.any() //接受一切上传的文件。
下面我们将会演示如何上传多个文件: html:
<form action="http://localhost:8080/" method="post" enctype="multipart/form-data">
<input type="file" name="files" value="指定文件" multiple>
<br><br>
<input type="submit" value="上传">
</form>
const express=require("express");
const multer=require('multer');
var upload=multer({dest:'./upload/'});
var fs = require('fs');
var app=express();
app.use("/",upload.array("files",5),function(req,res,next){
req.files.forEach(function(ele,index){
console.log(ele);
var oldFile=ele.destination+ele.filename; //指定旧文件
var newFile=ele.destination+ele.originalname; //指定新文件
fs.rename(oldFile,newFile,function(err){
err?console.log('上传失败!'):console.log('上传成功!');
});
});
res.send("成功上传");
});
app.listen(8080);