Express 框架

一、使用 express 命令 来快速从创建一个项目目录

1、全局安装Express及express-generator

命令:

$ npm install  -g express 

$ npm install  -g express-generator

2、创建脚手架

命令:

$ 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上手非常简单,首先新建一个项目目录,假定叫做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$/')
})

1、基础路由

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/loginhttp://127.0.0.1:8080/registe都能进入不同路由。

2、动态路由

路由参数被命名为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)
})

3、路由模块化

使用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)

四、get请求

通过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);

五、post请求

设置解析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渲染

1、应用层中间件

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);

2.路由中间件

路由级中间件和应用级中间件类似,只不过他需要绑定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);

3.错误处理中间件

顾名思义,它是指当我们匹配不到路由时所执行的操作。错误处理中间件和其他中间件基本一样,只不过其需要开发者提供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);

4、内置的中间件

  1. express.static
  2. express.json
  3. express.urlencoded

5、第三方中间件

  1. 网址:http://expressjs.com/en/guide/using-middleware.html
  2. 比如:body-parsercompressioncookie-parsermorganresponse-timeserve-staticsession

七、cookie

安装

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的参数说明:

  1. domain: 域名
  2. name=value:键值对,可以设置要保存的 Key/Value,注意这里的 name 不能和其他属性项的名字一样
  3. Expires: 过期时间(秒),在设置的某个时间点后该 Cookie 就会失效,如 expires=Wednesday, 09-Nov-99 23:12:40 GMT。
  4. maxAge: 最大失效时间(毫秒),设置在多少后失效 。
  5. secure: 当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才有效 。
  6. Path: 表示 在那个路由下可以访问到cookie。
  7. httpOnly:是微软对 COOKIE 做的扩展。如果在 COOKIE 中设置了“httpOnly”属性,则通过程序(JS 脚本、applet 等)将无法读取到COOKIE 信息,防止 XSS 攻击的产生 。
  8. singed:表示是否签名cookie, 设为true 会对这个 cookie 签名,这样就需要用 res.signedCookies 而不是 res.cookies 访问它。被篡改的签名 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

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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值