博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Node.js之Express四
阅读量:7235 次
发布时间:2019-06-29

本文共 8345 字,大约阅读时间需要 27 分钟。

Express提供的大部分功能是通过中间件函数完成的,这些中间件函数在Node.js收到请求的时点和发送响应的时点之间执行。Express的Connect模块提供了中间件框架,可以方便的在全局或路径级别或为单个路由插入中间件功能。Express建立在connect NPM模块上,提供了connect所提供的底层中间件支持。

一、在全局范围内把中间件分配给某个路径

要对所有路由指定中间件,可以在Express app对象上实现use()方法。

use([path],middleware)

path 变量可选,默认为/.意味所有的路径 middleware参数是一个函数,它的语法如下

function(req,res,next)

req:Request对象  res:Response对象  next是要执行的下一个中间件函数

var express=require('express');

var bodyParser=require('body-parser');

var app=express();

app.use('/',bodyParser());

每个中间件组件都有一个构造函数,它返回相应的中间件功能。

二、把中间件分配给单个路由

可以通过把一个单独的路由放在path参数后来对其应用body-parser中间件。例如下面的代码:

var express=require('express');

var bodyParser=require('body-parser');

var app=express();

app.get('/parsedRoute',bodyParser(),function(req,res))

{

     res.send('This request was logged.');

}

三、添加多个中间件函数

可以根据需要在全局范围和路由上分配任意多的中间件函数。

var express=require('express');

var bodyParser=require('body-parser');

var cookieParser=require('cookie-parser');

var session=require('cexpress-session');

var app=express();

app.use('/',bodyParser()).use('/',cookieParser()).use('/',session());

在分配函数的顺序就是它们在请求中被应用的顺序,一些中间件函数需要被添加在别的中间件函数前面。

四、使用query中间件

query中间件将一个查询字符串从URL转换为Javascript对象,并将其保存为Request对象的query属性。从Express4.x开始,此功能在内置请求解析器中存在,不需要额外的中间件。

五、提供静态文件服务

static中间件是很常用的Express中间件。static中间件可以直接从磁盘对客户端请求静态文件服务。可以使用static中间件支持不会改变的Javascript文件、CSS文件、图像文件和HTML文件之类的东西。

express.static(path,[options])

path:指定将在请求中引用的静态文件所在的根路径

options允许设置一下属性:

maxage:浏览器缓存maxAge(最长保存时间),以毫秒为单位,默认0.

hidden:true表示启用隐藏文件传输功能。默认false。

redirect:true表示若请求路径是一个目录,则该请求将被重定向到有一个尾随/的路径默认true。

index:根路径的默认文件名。默认为index.html.

var express = require('express');var app = express();app.use('/', express.static('./static'), {maxAge: 60*60*1000});app.use('/images', express.static( '../images'));app.listen(8080);

  上面实现了两个static路径:第一个把路由/映射到指定的名为static的子目录,第二个是把路由/images映射到一个对等的名为images的目录

六、处理POST正文数据

Express的body-parser中间件试图解析请求的正文中的JSON数据,把它们正确的格式化为Request对象的req.body属性。

var express = require('express');var bodyParser = require('body-parser');var app = express();app.use(bodyParser.urlencoded({ extended: true }));app.use(bodyParser.json());app.get('/', function (req, res) {  var response = '
' + 'First:
' + 'Last:
' + '
'; res.send(response);});app.post('/',function(req, res){ var response = '
' + 'First:
' + 'Last:
' + '
' + '

Hello ' + req.body.first + '

'; res.type('html'); res.end(response); console.log(req.body);});app.listen(8088);

上面的代码在从浏览器输入地址后走get请求返回响应,提交表单采用post请求,可以通过req.body.first来获取表单数据。

七、发送和接收cookie

 Express提供的Cookie-parser中间件使得处理cookie非常简单。cookie-parser中间件从一个请求解析cookie并将它们作为一个Javascript对象存储在req.cookies属性中。  express.cookie-parser([secret])

可选的secret字符串参数利用secret字符串在cookie内部签署来防止cookie的篡改。

要在响应中设置cookie,可以使用res.cookie()方法。

res.cookie(name,value,[options])

具有指定的名称和值参数的一个cookie被添加到响应中。options参数允许你设置cookie中的以下属性:

maxage:cookie过期前的生存时间

httpOnly:true表示cookie只能服务器访问,不能通过客户端Javascript访问

signed:true表示cookie将被签署,需要使用req.signedCookie对象,而不是req.cookie对象来访问它。

path:该cookie应用的路径。

var express = require('express');var cookieParser = require('cookie-parser');var app = express();app.use(cookieParser());app.get('/', function(req, res) {  console.log(req.cookies);  if (!req.cookies.hasVisited){    res.cookie('hasVisited', '1',                { maxAge: 60*60*1000,                  httpOnly: true,                  path:'/'});  }  res.send("Sending Cookie");});app.listen(8080);

 八、实现会话

 Express中cookie-session中间件提供了对基本会话的支持。cookie-session会话中间件在底层利用cookie-parser中间件,需要在添加cookie-session前先添加cookie-parser。res.cookie([options])

options允许设置以下属性:

key:用于标识会话的cookie名称

secret:用来签署会话cookie的字符串,用来防止cookie窃取

cookie:一个对象,定义cookie设置,包括maxage、path、httponly和signed.默认{path:'/',httpOnly:true,maxage:null}.

proxy:true将导致Express通过x-forwarded-proto设置安全cookie,信任反向代理。

当cookie-session被实现时,会话被存储为req.session对象。你对req.session做的任何更改都会跨越来自同一个浏览器的多个请求流动。

var express = require('express');var cookieParser = require('cookie-parser');var cookieSession = require('cookie-session');var app = express();app.use(cookieParser());app.use(cookieSession({secret: 'MAGICALEXPRESSKEY'}));app.get('/library', function(req, res) {  console.log(req.cookies);  if(req.session.restricted) {    res.send('You have been in the restricted section ' +              req.session.restrictedCount + ' times.');  }else {    res.send('Welcome to the library.');  }});app.get('/restricted', function(req, res) {  req.session.restricted = true;  if(!req.session.restrictedCount){    req.session.restrictedCount = 1;  } else {    req.session.restrictedCount += 1;  }  res.redirect('/library');});app.listen(8080);

 九、应用基本的HTTP身份验证

Express中间件的另一个常见用途是应用基本的HTTP身份验证。HTTP身份验证使用Authorization标头从浏览器向服务器发送编码后的用户名和密码。如果浏览器中没有存储URL的授权信息,浏览器会自动启动一个基本的登录对话框,让用户输入用户名和密码。

Express的basic-auth-connect中间件函数提供对处理基本的hTTP身份验证的支持。

var basicAuth=require('basic-auth-connect');

express.basicAuth(function(user,pass){});

传递到basic-auth-connect的函数接受用户名和密码。如果是正确的则返回true。通常在数据库中存储用户名密码,在authentication函数中检索要验证的用户对象。

对于单个路由的验证和中间件分配到单个路由是一样的。

var express = require('express');var basicAuth = require('basic-auth-connect');var app = express();app.listen(8080);app.use(basicAuth(function(user, pass) {  return (user === 'testuser' && pass === 'test');}));app.get('/', function(req, res) {  res.send('Successful Authentication!');});
var express = require('express');var basicAuth = require('basic-auth-connect');var app = express();var auth = basicAuth(function(user, pass) {  return (user === 'user1' && pass === 'test');});app.get('/library', function(req, res) {  res.send('Welcome to the library.');});app.get('/restricted', auth, function(req, res) {  res.send('Welcome to the restricted section.');});app.listen(8080);

 十、实现会话身份验证

基于HTTP身份验证的一个主要缺点是只要证书被存储,登录就一直存在,这不是很安全。Express内的session中间件附加一个Session对象req.session到Request对象来提供会话功能。提供了下面几个方法:

regenerate([callback]) :移除并创建一个新的req.session对象,重置会话

destory([callback]):移除req.session对象

save([callback]):保存会话数据

touch([callback]):为会话cookie重置maxage计数

cookie:指定把会话链接到浏览器的cookie对象

var express = require('express');var bodyParser = require('body-parser');var cookieParser = require('cookie-parser');var session = require('express-session');var crypto = require('crypto');function hashPW(pwd){  return crypto.createHash('sha256').update(pwd).         digest('base64').toString();}var app = express();app.use(bodyParser.urlencoded({ extended: true }));app.use(bodyParser.json());app.use(cookieParser('MAGICString'));app.use(session());app.get('/restricted', function(req, res){  if (req.session.user) {    res.send('

'+ req.session.success + '

' + '

You have entered the restricted section

' + ' logout'); } else { req.session.error = 'Access denied!'; res.redirect('/login'); }});app.get('/logout', function(req, res){ req.session.destroy(function(){ res.redirect('/login'); });});app.get('/login', function(req, res){ var response = '

' + 'Username:
' + 'Password:
' + '
'; if(req.session.user){ res.redirect('/restricted'); }else if(req.session.error){ response +='

' + req.session.error + '

'; } res.type('html'); res.send(response);});app.post('/login', function(req, res){ //user should be a lookup of req.body.username in database var user = {name:req.body.username, password:hashPW("myPass")}; if (user.password === hashPW(req.body.password.toString())) { req.session.regenerate(function(){ req.session.user = user; req.session.success = 'Authenticated as ' + user.name; res.redirect('/restricted'); }); } else { req.session.regenerate(function(){ req.session.error = 'Authentication failed.'; res.redirect('/restricted'); }); res.redirect('/login'); }});app.listen(8080);

 十一、创建自定义中间件

使用Express,可以自己创建中间件。只要提供一个接受Request对象作为第一个参数,Response对象作为第二个参数,next作为第三个参数的函数。next函数是一个通过中间件框架传递的函数,它指向下一个要执行的中间件函数,所以必须在退出自定义函数之前调next(),否则处理程序将永远不会被调用。下面demo就是自定义的一个中间件函数,这个函数在把查询字符串发送到处理程序之前把该字符串从URL中剥离。

var express = require('express');var app = express();function queryRemover(req, res, next){  console.log("\nBefore URL: ");  console.log(req.url);  req.url = req.url.split('?')[0];  console.log("\nAfter URL: ");  console.log(req.url);  next();};app.use(queryRemover);app.get('/no/query', function(req, res) {  res.send("test");});app.listen(80);

 

转载地址:http://cnlfm.baihongyu.com/

你可能感兴趣的文章
利用js动态创建<style>
查看>>
Net分布式系统之二:CentOS系统搭建Nginx负载均衡(下)
查看>>
App上线Check List
查看>>
广播接收者实现IP拨号
查看>>
关于mysql编码问题
查看>>
c++ typedef和#define的作用范围
查看>>
Ansible系列(七):执行过程分析、异步模式和速度优化
查看>>
正则表达式matcher.group用法
查看>>
TCP/IP(三)数据链路层~2
查看>>
使用Json让Java和C#沟通的方法
查看>>
小米路由Mini刷Breed, 潘多拉和LEDE
查看>>
tornado日志使用详解
查看>>
[Flume][Kafka]Flume 与 Kakfa结合例子(Kakfa 作为flume 的sink 输出到 Kafka topic)
查看>>
ajax的工作原理
查看>>
Android GIS开发系列-- 入门季(14)FeatureLayer之范围查询
查看>>
IIC接口下的24C02 驱动分析
查看>>
fragmentTabHost 使用示例
查看>>
oop思维意识,类 模块命名空间,类扩展之继承 、组合、mixin三种模式
查看>>
让gcc和gdb支持intel格式的汇编
查看>>
Shell脚本8种字符串截取方法总结
查看>>