Node.js之Express四
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: **});
app.use('/images', express.static( '../images'));
app.listen();
上面实现了两个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 = '<form method="POST">' +
'First: <input type="text" name="first"><br>' +
'Last: <input type="text" name="last"><br>' +
'<input type="submit" value="Submit"></form>';
res.send(response);
});
app.post('/',function(req, res){
var response = '<form method="POST">' +
'First: <input type="text" name="first"><br>' +
'Last: <input type="text" name="last"><br>' +
'<input type="submit" value="Submit"></form>' +
'<h1>Hello ' + req.body.first + '</h1>';
res.type('html');
res.end(response);
console.log(req.body);
});
app.listen();
上面的代码在从浏览器输入地址后走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', '',
{ maxAge: **,
httpOnly: true,
path:'/'});
}
res.send("Sending Cookie");
});
app.listen();
八、实现会话
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 = ;
} else {
req.session.restrictedCount += ;
}
res.redirect('/library');
});
app.listen();
九、应用基本的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();
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();
十、实现会话身份验证
基于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('<h2>'+ req.session.success + '</h2>' +
'<p>You have entered the restricted section<p><br>' +
' <a href="/logout">logout</a>');
} 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 = '<form method="POST">' +
'Username: <input type="text" name="username"><br>' +
'Password: <input type="password" name="password"><br>' +
'<input type="submit" value="Submit"></form>';
if(req.session.user){
res.redirect('/restricted');
}else if(req.session.error){
response +='<h2>' + req.session.error + '<h2>';
}
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();
十一、创建自定义中间件
使用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('?')[];
console.log("\nAfter URL: ");
console.log(req.url);
next();
};
app.use(queryRemover);
app.get('/no/query', function(req, res) {
res.send("test");
});
app.listen();
Node.js之Express四的更多相关文章
- node.js和express.js安装和使用步骤 [windows]
PS: NODEJS:https://nodejs.org NPM:https://www.npmjs.com/ 一.node.js安装与配置 到https://nodejs.org/en/downl ...
- Node.js基于Express框架搭建一个简单的注册登录Web功能
这个小应用使用到了node.js bootstrap express 以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...
- node.js之express框架
之前学习过node.js接触过express框架,最近为了编写一个mock server正好用到了express.下面正好就跟大家介绍一下关于express.今天的内容主要围绕这么几个方面? expr ...
- Code Your First API With Node.js and Express: Set Up the Server
How to Set Up an Express API Server in Node.js In the previous tutorial, we learned what the REST ar ...
- Node.js、express、mongodb 实现分页查询、条件搜索
前言 在上一篇Node.js.express.mongodb 入门(基于easyui datagrid增删改查) 的基础上实现了分页查询.带条件搜索. 实现效果 1.列表第一页. 2.列表第二页 3. ...
- Node.js、express、mongodb 入门(基于easyui datagrid增删改查)
前言 从在本机(win8.1)环境安装相关环境到做完这个demo大概不到两周时间,刚开始只是在本机安装环境并没有敲个Demo,从周末开始断断续续的想写一个,按照惯性思维就写一个增删改查吧,一方面是体验 ...
- node.js框架express的安装
node.js框架express的安装 首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录. $ mkdir myapp $ cd myapp 通 ...
- Node.js系列-express(上)
前言 Node.js系列的第一篇:http,大概描述了通过使用node.js内置的api创建一个服务并监听request实现简单的增删改查.现在,我们就通过通读express官网及使用express框 ...
- node.js,express入门看详细篇
先最简单的代码 安装 npm install express app.js 代码内容 const express = require('express') const app = express() ...
随机推荐
- Mina Session
Chapter 4 - Session The Session is at the heart of MINA : every time a client connects to the server ...
- CodeForces 540B School Marks
http://codeforces.com/problemset/problem/540/B School Marks Time Limit:2000MS Memory Limit:26214 ...
- 【BZOJ3238】[AHOI2013]差异
[BZOJ3238][AHOI2013]差异 题面 给定字符串\(S\),令\(T_i\)表示以它从第\(i\)个字符开始的后缀.求 \[ \sum_{1\leq i<j\leq n}len(T ...
- Android------------------的资源文件的学习
一.style的学习 用法: 使用: 使用系统自带的style的风格 使用: 效果: 二.drawable的使用 selector是一个xml文件进行加载使用的: 文件名叫做buttonselecto ...
- Python 读取大文件的方式
对于读取容量小的文件,可以使用下面的方法: with open("path", "r") as f: f.read() 但是如果文件容量很大,高达几个G或者十几 ...
- 什么是Ajax?Ajax的原理是什么?Ajax的核心技术是什么?Ajax的优缺点是什么?
Ajax是一种无需重新加载整个网页,能够更新部分网页的技术.Asynchronous JavaScript and XML的缩写,是JavaScript.XML.CSS.DOM等多个技术的组合. Aj ...
- Python中获取当前时间 获取当前时间前几天的代码
当然 需要引入 datetime import datetime 获取当前日期:datetime.datetime.now().strftime('%Y-%m-%d') 获取当前日期前七天日期: no ...
- tomcat JNDI Resource 配置
最近公司的项目慢慢开始向Maven项目迁移, 部分配置文件公共组也帮我们做了些改动,其中在spring的applicationContext.xml中看到了数据连接bean存在两个,一个是jndi 一 ...
- Zookeeper之Curator(1)客户端基本的创建,删除,更新,查找操作api
Curator Framework提供了简化使用zookeeper更高级的API接口.它包涵很多优秀的特性,主要包括以下三点: 自动连接管理:自动处理zookeeper的连接和重试存在一些潜在的问题: ...
- js 从基础入门 到放弃 001
快速入门 JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中: <html> <head> <s ...