介绍
核心功能:
- 允许设立中间件响应 http 请求;
- 定义用于执行 HTTP 方法和 URL 不同动作的路由表;
- 允许动态渲染基于参数传递给模板 HTML 页面
安装
-
cmd 下载
$ npm install express --save
上述命令在本地 node_modules 目录目录保存安装,并创建一个目录 express 在 node_modules 里,应该使用 express 安装以下几个重要的模块
-
body-parser: 处理 JSON,Raw,Text,URL 编码的表单数据的中间件
-
cookie-parser: 解析 cookie 头 ,填充 req.cookies 通过cookie 名字键控对象
-
multer: 处理 multipart/formData 的中间件
$ npm install body-parser --save $ npm install cookie-parser --save $ npm install multer --save
-
-
package.json 间接安装
mkdir express//创建 express 文件夹
express 目录下创建 package.json 文件
{ "name": "express", "description": "express test app", "version": "0.0.1", "private": "true", "dependencies": { "express": "3.x" } }
cmd 执行下述命令
npm install
mkdir 一个 server.js
const express = require("express"); var server = express();
在此实例中,你可以通过
server.VERB()
定义路由,req
和res
对象是node 原生提供的,可执行res.pipe()
,req.on('data',callback)
等任何命令在未安装 Express 的情况下Express 给这些对象加了一个封装好的方法,比如
res.send()
,它会设置 Content-Lengthserver.get('/hello.txt',function(req,res){ res.send('Hello World'); });
执行
server.listen()
绑定并监听连接server.listen(8080,function(){ console.log('Listening on port %d',server.address().port); });
Hello world 实例
下述为一个基本的Express 应用程序,可启动服务器,侦听端口8080等待连接,
const express = require("express");
var app = express();
app.get('/',function(req,res){
res.send('Hello World!');
})
var server = app.listen(8080,function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
})
保存上述代码至文件名为 server.js 的文件中,并在 cmd 中$ node server.js
看到输出
Example app listening at http://0.0.0.0:8080
在任何浏览器打开 http://127.0.0.1:8080/
Request & Response
Express 应用程序利用一个回调函数,它的参数是 request 和 response 对象
app.get('/',function(req,res){
// --
})
- Request 对象 – 请求对象表示HTTP请求和具有用于请求查询的字符串,参数,主体,HTTP报头等属性
- Response 对象 – 响应对象表示HTTP响应Express应用程序发送时,他得到一个HTTP请求
基本的路由
路由,确定应用程序如何响应客户机请求到特定端点,这是一个URI(路径)和特定的HTTP请求方法(GET,POST等)
扩展上述 Hello World 程序添加功能
const express = require("express");
var app = express();
//This responds with "Hello World" on the homepage
app.get('/',function(req,res){
console.log('Got a GET request for the homepage');
res.send('Hello GET');
})
//This responds a POST request for the homepage
app.post('/',function(req,res){
console.log('Got a POST request for the homepage');
res.send('Hello POST');
})
//This responds a Delete request for the /del_user page
app.delete('/',function(req,res){
console.log('Got a DELETE request for /del_user');
res.send('Hello DELETE');
})
//This responds a GET request for the /list_user page
app.get('/',function(req,res){
console.log('Got a GET request for /list_user');
res.send('Hello Listing');
})
//This responds a GET request for abcd,abxcd,ab123cdcon,and so on
app.get('/',function(req,res){
console.log('Got a GET request for /ab*cd');
res.send('Page Pattern Match');
})
var server = app.listen(8080,function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
})
提供静态文件服务
express 提供内置中间件 express.static 用于处理静态文件,如图像,CSS,JS等
只需在那里把静态资源,到 express.static 中间件开始直接服务于文件传递目录得名称
【假设】把图片,css,JS文件放在指定目录 public
app.use(express.static('public'));
将上述代码添加至 “Hello World ”应用程序以添加处理静态文件功能
GET方法
栗子
通过使用HTML表单使用GET方法传递两个值。我们将使用server.js路由器里面 process_get 来处理该输入
//index.html
<html>
<body>
<form action="http://127.0.0.1:8081/process_get" method="GET">
First Name: <input type="text" name="first_name"> <br>
Last Name: <input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html>
const express = require("express");
var app = express();
app.use(express.static('publuc'));
app.get('/',function(req,res){
res.readFile(__dirname + '/' + 'index.html');
});
app.get('/process_get',function(req,res){
response = {
first_name:req.query.first_name,
last_name:req.query.last_name
};
console.log(response);
res.end(JSON.stringify(response));
});
var server = app.listen(8081,function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
});
File 上传
创建一个文件上传表单。这种形式的方法属性设置为POST,以及enctype属性设置为 multipart/form-data
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="http://127.0.0.1:8081/file_upload" method="POST"
enctype="multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
</html>
const express = require('express');
const app = express();
const fs = require('fs');
var bodyParser = require('body-parser');
var multer = require('multer');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended:false}));
app.use(multer({dest:'/txt/'}));
app.get('/index.html',function(req,res){
res.readFile(__dirname + '/' + 'index.html');
})
app.post('/file_upload',function(req,res){
console.log(req.files.file.name);
console.log(req.files.file.path);
console.log(req.files.file.type);
var file = __dirname + "/" + req.files.file.name;
fs.readFile(req.files.file.path,function(err,data){
fs.writeFile(file,data,function(err){
if(err){
console.log(err);
}else{
response = {
message:'File uploaded successfully',
filename:req.files.file.name
};
}
console.log(response);
res.end(JSON.stringify(response));
});
});
})
var server = app.listen(8081,function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port)
})
cookie,session
-
cookie:
浏览器保存数据,每次请求均会被带来,保存于客户端,不安全,内存有限,可独立存在
-
发送cookie
res.cookie(name,value,{path:'/',maxAge://最长保存时间ms })
-
读取–中间件(cookie-parser)
const cookieParser = require('cookie-parser'); server.use(cookieParser('密钥'));
-
删除
server.use('/',function(req,res){ res.clearCookie('user'); });
-
加密
-
req.sercet = '密钥'
res.cookie(name,value,{signed:true});
‘【栗子】
req.secret = 'abcd'; res.cookie('user','meng',{signed:true}); console.log(req.signedCookies); //签名的cookie console.log(req.cookies); //未签名的cookie
-
-
-
session–(cookie-session)
数据保存于服务端,安全,内存无限,基于cookie 实现的,不可独立存在
若想使用
server.use(cookieSession())
,必需有server.use(cookieParser)
cookie 中有一个 sessionID,服务器利用 sessionID 找到 session 文件,读取,写入
-
隐患:session 劫持,cookie-session 强制有密钥
-
获取
server.use(cookieSession(){ name: , keys:[], maxAge: })
-
处理
server.use('/',function(req,res){ req.session['count'] = ; });
-
删除
delete req.session;
-
Cookies 管理
可使用发送 cookie 来Node.js 加载服务器,他可处理使用下面的中间件选项、
【栗子】
打印所有客户端发送的cookie
const express = require('express');
const cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get('/',function(req,res){
console.log('Cookies: ',req.cookies)
})
app.listen(8081);
body-parser
http 请求中,put,post,patch 三种请求方法中包含请求体,即request,在 Node.js 原生的 http 模块中,请求体是要基于流的方式来接受和解析的
body-parser 是一个 http 请求体解析的中间件,使用此模块可解析 JSON,Raw,Text,URL-encoded 格式的请求体
Node 原生的 http 模块中,是将用户请求数据封装于用于请求的对象 req 中,此对象是一个 IncomingMessage,也为一个可读流文件。原生Http 服务器,或不依赖第三方解析模块时,可用下面的方法请求并且解析请求体
const http = require("http");
http.createServer(function(req,res){
if(req.method.toLowerCase() == 'post'){
var body = '';
//接收数据
req.on('data',function(chunk){
body += chunk;
});
//开始解析
req.on('end',function(){
if(req.headers['content-type'].indexOf('application/json') !== -1){
JSON.parse(body);
}else if(req.headers['content-type'].indexOf('application/octet-stream')!==-1){
//Raw 格式请求体解析
}else if(req.headers['content-type'].indexOf('text/plain')!==-1){
//text 格式请求体解析
}else if(req.headers['content-type'].indexOf('application/x-www-form-urlencoded')){
//url-encoded 格式请求体解析
}else{
//其他格式解析
}
});
}else{
res.end('其他方式提交');
}
}).listen(8080);
在实际项目中,不同路径可能要求用户使用不同的内容类型,body-parser还支持为单个express路由添加请求体解析
var express = require('express');
var bodyParser = require('body-parser');
var app = new express();
//创建application/json解析
var jsonParser = bodyParser.json();
//创建application/x-www-form-urlencoded
var urlencodedParser = bodyParser.urlencoded({extended: false});
//POST /login 中获取URL编码的请求体
app.post('/login', urlencodedParser, function(req, res){
if(!req.body) return res.sendStatus(400);
res.send('welcome, ' + req.body.username);
})
//POST /api/users 获取JSON编码的请求体
app.post('/api/users', jsonParser, function(req,res){
if(!req.body) return res.sendStatus(400);
//create user in req.body
})
指定请求类型
指定时可以通过在解析方法中添加type参数修改指定Content-Type的解析方式。
比如,对text/plain内容类型使用JSON解析
app.use(bodyParser.json({type: 'text/plain'}))
body-parser模块的API
当请求体解析之后,解析值会被放到req.body属性中,当内容为空时候,为一个空对象{}
bodyParser.json()--解析JSON格式
bodyParser.raw()--解析二进制格式
bodyParser.text()--解析文本格式
bodyParser.urlencoded()--解析文本格式