express框架使用详解

express框架介绍与安装

express框架其实是nodejs内置http模块的扩展,主要用来:

1.快速搭建nodejs项目:这点功能有点类似于java里面的maven,使用express建立好的项目结构有固定的目录名称,每个目录都约定俗成的     存放着应该存放的文件,比如public目录一般用来存放资源文件

2.完成路由功能:在没有使用express之前,如果我们想要实现路径的路由,需要使用http模块获取url,加上n多个if  else判断来实现,在         express里面实现起来相当简单方便、易于阅读

3.express的中间件:中间件(middleware)说白了就是处理HTTP请求的函数,用来完成各种特定的任务,比如检查用户是否登录、处理数据、以及其他在需要最终将数据发送给用户之前完成的任务。它最大的特点就是,一个中间件处理完,可以决定是否再传递给下一个中间件。

全局安装:

npm install -g express

本地安装:

npm install  express  --save-dev

package.json:

image.png

express快速上手

在安装好了express之后,我们来编写一个程序快速入门,新建一个a.js,编辑内容如下:

var express = require('express');
var app = express();

app.use(function(req,res){
	console.log("第一个express快速入门");
});

app.listen(8080);

使用node运行a.js:

D:\zhao\nodews>node a

运行之后,程序阻塞在这里,此时在浏览器输入:http://localhost:8080 或者http://localhost:8080/abc或者http://localhost:8080/abc/123abc等待,都会输出第一个express快速入门这句话:

image.png

至此,express快速入门就完成了。

express的use方法

前边express的快速入门章节我们使用了express的use方法:

app.use(function(req,res){
	console.log("第一个express快速入门");
});

其格式是:app.use([path,] callback [, callback...])

解释:当path不写的时候,所有请求都会被拦截,写上path则表示拦截path指定的路径。

           回调函数的参数req、res分别表示请求对象和相应对象,除了这两个参数,还有第三个参数next,这个next是个函数,如果调用了这个函数,则表示继续执行下一个next。

使用use拦截指定路径,编写a.js:

var express = require('express');
var app = express();

app.use("/login",function(req,res){
	console.log("登录");
});

app.use(function(req,res){
	console.log("第一个express快速入门");
});

app.listen(8080);

使用命令node a运行,输入http://localhost:8080/login访问,控制台打印如下信息:

image.png

但是修改上边的代码,把两个use交换下位置:

app.use(function(req,res){
	console.log("第一个express快速入门");
});
app.use("/login",function(req,res){
	console.log("登录");
});

再访问http://localhost:8080/login的时候,将只打印“第一个express快速入门”这句话,这是因为,你并没有调用use回调函数的第三个参数next,next决定着是否继续按顺序往下执行下一个中间件(express里面的中间件就是一个函数)。我们修改a.js代码:

var express = require('express');
var app = express();

app.use(function(req,res,next){
	console.log("第一个express快速入门"+req.path);
	next();
});
app.use("/login",function(req,res){
	console.log("登录");
});

app.listen(8080);

再访问http://localhost:8080/login结果如下:

image.png

express的app.get与app.post方法

前边说了express的app.use方法拦截指定的请求地址,但是我们还知道http请求分为get请求、post请求、update请求等等,都用use拦截显得有点不直观,所以express又给use方法取了很多别名,分别对应着http的get请求、post请求、update请求等,这就是express里面的app.get和app.post方法。也就是说,对于请求的拦截处理,你可以使用use也可以使用get或者post来分担use的功能。

app.get(path, callback [, callback ...]):用于拦截get请求

app.post(path, callback [, callback ...]):用于拦截post请求

我这里就以app.get方法为例吧,编写a.js:

var express = require('express');
var app = express();

app.get("/login",function(req,res){
	console.log("登录");
});
app.get("/listUsers",function(req,res){
	console.log("获取用户列表");
});

app.listen(8080);

运行node a,分别访问对应地址,结果如下:

D:\zhao\nodews>node a
登录
获取用户列表

nodejs使用express向浏览器发送数据或者页面

前面我们编写的基于express的程序比较简单,都是在中间件里面直接使用console.log打印一句话就了事了,这样子只能在控制台调试一下运行结果,如果我想向浏览器发送数据或者html页面该怎么做呢?我们使用nodejs的http模块的时候,在顶级路由判断的模块,假如要返回一个登陆页面login.html,我们就需要使用nodejs的fs模块把login.html读取近来并写入浏览器,在express里面的原理自然也是一样的,只是给我们提供的方法不同罢了。这里面express主要给我们提供了两个很常用的函数,

res.send([body]):用于向浏览器写入数据,比如字符串等

res.sendFile(path [, options] [, fn]):用于向浏览器写入文件,这里的path一定要是绝对路径才可以。

编写a.js:

var express = require('express');
var app = express();

app.get("/login",function(req,res){
	res.sendFile(__dirname+"/test.html");
});
app.get("/listUsers",function(req,res){
	res.send("用户列表");
});

app.listen(8080);

运行:

D:\zhao\nodews>node a

访问login:

image.png

访问listUsers:

image.png

__dirname:在nodejs中用于获取当前工作目录的绝对路径,非常方便。当然,你不使用__dirname而是使用fs模块来获取绝对路径也是可以的,最终都是殊途同归的。

var express = require('express');
var fs=require('fs');
var app = express();

app.get("/login",function(req,res){
	fs.realpath("./test.html",function(err,data){
		res.sendFile(data);
	});
});
app.get("/listUsers",function(req,res){
	res.send("用户列表");
});

app.listen(8080);

访问结果是一样的。

express的express.static方法处理静态资源

  前边的程序已经可以向浏览器返送数据或者文件了,但是还有两个致命的问题没有解决:

①、当用户输入的请求路径不存在该怎么处理?

②、当向浏览器写入文件的时候,如果文件引入了外部的css、js、或者是图片,在页面里面并不能正常显示,又该怎么处理呢?

针对上面两个问题,express框架给出的解决方案分别是:

因为app.use就可以实现拦截所有请求路径的功能,所有针对第一个问题,我们可以用app.use来解决。

express.static(root, [options]):处理资源文件,root表示的静态资源文件所在的目录。

编写a.js:

var express = require('express');
var app = express();

//表示当前目录下面的public目录是静态资源文件所在目录
app.use(express.static('./public'));

app.get("/login",function(req,res){
	res.sendFile(__dirname+"/test.html");
});
app.get("/listUsers",function(req,res){
	res.send("用户列表");
});
//处理不存在的路径
app.use(function(req,res){
	res.send("请求路径不存在");
})
app.listen(8080);

node a运行。

D:\zhao\nodews>node a

public的目录结构,在windows下可以使用tree /f命令查看目录结构:

image.png

test.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>用户登录</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="javascripts/demo_compiled.js"></script>
    <style type="text/css">
     
    </style>
  </head>
  <body>
    <form>
<input type="text">
<input type="password">
<input type="button" value="登录">
</form>
<img src="imgs/logo.png">
<p>
我是登录页面
</p>
  </body>
</html>

注意:这里引入资源文件的时候,不要再加入public了,因为public已经使用app.use(express.static('./public'));映射为资源文件所在目录了,因此,在html文件中引入的资源文件是目录是基于public的。

style.css:

p {
  color: #4D926F;
}

demo_compiled.js:

console.log("我是外部引入的js文件");

启动之后,在浏览器中访问不存在的路径:

image.png

访问http://localhost:8080/login:

image.png

上面两个问题就解决了。

使用express-generator快速生产nodejs项目结构

安装:

D:\zhao\nodews>npm install -g express-generator
C:\Users\zhao\AppData\Roaming\npm\express -> C:\Users\zhao\App
Data\Roaming\npm\node_modules\express-generator\bin\express-cli.js
C:\Users\zhao\AppData\Roaming\npm
`-- express-generator@4.16.0
  +-- commander@2.13.0
  +-- ejs@2.5.7
  +-- minimatch@3.0.4
  | `-- brace-expansion@1.1.11
  |   +-- balanced-match@1.0.0
  |   `-- concat-map@0.0.1
  +-- mkdirp@0.5.1
  | `-- minimist@0.0.8
  `-- sorted-object@2.0.1

安装好了express-generator之后,就可以使用命令快速生成nodejs项目的基本目录结构了:

D:\zhao\nodews>express project1

上面的命令表示把生成的目录结构放在proejct1这个文件夹下面,tree /f查看project1的目录结构:

image.png

生成完成。

按照package.json来下载相关依赖:

D:\zhao\nodews\project1>npm install

安装完成之后,使用命令npm start,即可启动这个生成的示例项目:

D:\zhao\nodews\project1>npm start

浏览器访问http://localhost:3000/,看到如下界面,ok:

image.png

访问会在后台打印日志:

D:\zhao\nodews\project1>npm start

> project1@0.0.0 start D:\zhao\nodews\project1
> node ./bin/www

GET / 200 1679.113 ms - 170
GET /stylesheets/style.css 200 8.379 ms - 111
GET /favicon.ico 404 64.803 ms - 1052
GET /users 200 2.854 ms - 23

 

express里的session使用

nodejs里面并不包含session模块,需要自行使用npm安装第三方支持session的模块,一般我都是用express-session.

npm install express-session --save-dev

image.png

我们使用这个插件来测验一下session,编写a.js:

let express = require('express');
let session=require('express-session');
var app=express();
//这里相当于初始化一下session,不加这一句后边的request.session依然是undefined
app.use(session({
	secret: 'secretstring',
    cookie: {maxAge:20*1000},
	resave:false,
    saveUninitialized:true
}));

//打印一下session
app.use(function(req,res,next){
	console.log(req.session);
	next();
});


app.get("/login",function(request,response){
	//设置session的值
	 request.session.username='zhao';
	 request.session.pwd='123456';
	 response.end("login success");
});

app.get("/",function(request,response){
	if(!request.session){
		response.end("no auth!");
	}else{
		if(request.session.username=='zhao'&&
		   request.session.pwd=='123456'){
			   response.end("index");
		 }else{
			 response.end("not equal");
		 }
	}
});
app.listen(8888);  
console.log('正在监听8888端口');

运行node a,访问并查看控制台的输出:

image.png

使用session成功,注意啊,这里不能使用nodejs原生的request和response,要使用经过express框架包装过的request和response。

express-session的配置项解释:

        name: 设置 cookie 中,保存 session 的字段名称,默认为 connect.sid 。

        store: session 的存储方式,默认存放在内存中,也可以使用 redis,mongodb 等。express 生态中都有相应模块的支持。

        secret: 通过设置的 secret 字符串,来计算 hash 值并放在 cookie 中,使产生的 signedCookie 防篡改。

        cookie: 设置存放 session id 的 cookie 的相关选项,默认为 (default: { path: ‘/’, httpOnly: true, secure: false, maxAge: null })

        genid: 产生一个新的 session_id 时,所使用的函数, 默认使用 uid2 这个 npm 包。

        rolling: 每个请求都重新设置一个 cookie,默认为 false。

        resave: 即使 session 没有被修改,也保存 session 值,默认为 true。

cookie的相关属性:

        name=value:键值对,要保存的值

        Expires: 过期时间(秒),在设置的某个时间点后该 Cookie 就会失效

        maxAge: 最大失效时间(毫秒),设置在多少后失效

        secure: 当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才有效

        path: 表示 cookie 影响到的路,如 path=/。如果路径不能匹配时,浏览器则不发送这个Cookie

        httpOnly:布尔值,如果在COOKIE中设置了“httpOnly”属性,则前端js脚本将无法访问该cookie,此时只能通过服务端来对cookie访问

express使用connect-redis持久化session信息到redis

  在“express里的session使用”这篇教程里面我使用了express-session包来存储session,默认的session是保存在服务器端的内存里面的,一般在项目里面我们都是把session存储在redis或者mogodb之中,express结合connect-redis包持久化session信息到redis里面。

首先安装connect-redis:

D:\zhao\nodews>npm install connect-redis --save-dev

安装完成之后package.json也新增了响应的依赖。

image.png

修改“express里的session使用”“”这篇教程里面的代码加入持久化session的代码:

let express = require('express');
let session=require('express-session');
let redisStore=require('connect-redis')(session);
var app=express();
//这里相当于初始化一下session,不加这一句后边的request.session依然是undefined
app.use(session({
  store:new redisStore({
    port: 6379,          // Redis port
    host: '192.168.28.113',   // Redis host
    db: 1
  }),
	secret: 'secretstring',
    cookie: {maxAge:20*1000},
	resave:false,
    saveUninitialized:true
}));

//打印一下session
app.use(function(req,res,next){
	console.log(req.session);
	next();
});


app.get("/login",function(request,response){
	//设置session的值
	 request.session.username='zhao';
	 request.session.pwd='123456';
	 response.end("login success");
});

app.get("/",function(request,response){
	if(!request.session){
		response.end("no auth!");
	}else{
		if(request.session.username=='zhao'&&
		   request.session.pwd=='123456'){
			   response.end("index");
		 }else{
			 response.end("not equal");
		 }
	}
});
app.listen(8888);  
console.log('正在监听8888端口');

相比之前的代码,本次做的更改如下红框中所示:

image.png

sotre的解释参见上面的解释,connect-redis的配置也是个对象,上面用到了三个:

port:要连接的redis的端口

host:要连接的reids所在机器的ip

db:把session信息放到redis的哪个数据库里面

其他还有可以使用的属性参见connect-redis在npmjs上的介绍https://www.npmjs.com/package/connect-redis。

到redis上查看:

image.png

nodejs使用express的res.json()返回json

 nodejs中使用原生的http内置模块返回json的话比较麻烦,我们使用nodejs开发web项目,大多数的时候都在使用express框架,返回json数据(json对象和json数组),我们来看看如何使用express框架返回json。

先看看使用http内置模块返回json,我想当然的使用response.json("{'data':'ok'}")来返回:

var server=http.createServer(function (request, response) {  
	if(request.url=='/list'){
		response.json("{'data':'ok'}");
	}else{
		response.writeHead(200, {'Content-Type': 'text/html'});  
		response.end('<h1>Hello World</h1> nodejs');  
	}
});
server.listen(8888);

报错:

TypeError: response.json is not a function

    at Server.<anonymous> (D:\zhao\nodews\a.js:23:12)

    at emitTwo (events.js:106:13)

    at Server.emit (events.js:191:7)

    at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:546:12)

    at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)

说明,你这个想当然是错误的,为了方便我们使用express框架来返回json:

var express = require('express');
var app = express();
 
app.use("/list",function(req,res){
	res.json("{'data':'ok'}");
});
 
app.use(function(req,res){
	res.send('<h1>Hello World</h1> nodejs');  
}); 
app.listen(8888);
console.log('正在监听8888端口');

运行结果:

image.png

我们知道,express是nodejs体系里的框架,它的请求对象req和响应对象res与nodejs内置模块中的请求对象req和响应对象res是不同的,express的对象包装了后者,因此用法也是不尽相同的。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值