Express框架

1. 课程介绍

◆ Express介绍(了解)

◆ Express安装及使用(掌握)

◆ Express路由(掌握)

◆ response响应对象(掌握)

◆ request请求对象(掌握)

◆ 中间件(了解)

2. Express介绍

Express 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用。

Express 框架核心特性:

n 可以设置中间件来响应 HTTP 请求。
n 定义了路由表用于执行不同的 HTTP 请求动作。
(url = 资源) 映射
n 可以通过向模板传递参数来动态渲染 HTML 页面。 模板引擎

3. Express使用

3.1. 简单使用(了解)

1、新建一个NodeJs项目文件夹

2、npm init 初始化项目配置文件(package.json 包描述文件)

package.json中

 **"scripts"**: {

 //命令 **"start"**:**"node ./index"
  **}

 npm start 执行”start”后面的代码。

3、安装express

npm install express --save

4、编写一个app.js使用express

 *//**导入**express**模块***var** **express** = *require*(**"express"**); *//**创建一个**express**应用***var** ***app*** = **express**(); *//**处理**"/"**请求****app***.get(**"/"**,**function**(req,res){
       *//**响应输出**“hello world”
       *res.send(**"Hello world"**);
 }); *//**启动服务器监听**3000**端口****app***.listen(3000,**function**(){
        ***console***.log(**"express app** **启动成功。。。****"**);
 });

5、启动服务器

node app.js

6、浏览器访问

3.2. Express-generator(重点)

为了快速的创建express项目,express团队为使用者提供了项目快速生成工具,express-generator

1、安装express-generator

npm i express-generator -g //全局安装

2、新建一个目录(或者找一个空目录)

F:\webproject (目录可以新建在任何位置,但最好不要中文路径)

3、通过命令创建express项目

express -e projecname(express代表在当前目录下面建立express项目 -e代表使用ejs模版引擎)

**express webapp **(代表在当前目录下面,新建一个webapp文件夹,然后在建立express项目)

项目结构:

bin : 执行文件,也是express项目启动文件。

public:公共的资源,浏览器可以直接访问的资源。(图片,js,css)

views:服务器端模块文件。

routes:路由处理器,处理浏览器发出不同url的处理程序。

/login function(){

//登录处理程序

}

app.js express应用的主文件,该文件主要用于整合其他第三方模块和配置express的系统参数。

4、安装依赖包

通过package.json

**"dependencies"**: { **"body-parser"**: **"~1.15.1"**, **"cookie-parser"**: **"~1.4.3"**, **"debug"**: **"~2.2.0"**, **"ejs"**: **"~2.4.1"**, **"express"**: **"~4.13.4"**, **"morgan"**: **"~1.7.0"**, **"serve-favicon"**: **"~2.3.0"** }

  **npm i**

5、启动express

node app需要设置监听端口
npm start
node ./bin/www

6、浏览器访问

3.3. Express服务器项目结构说明

 bin: 执行文件,也是express项目启动文件。

 public: 公共的资源(nodejs不做处理),浏览器可以直接访问的资源,相当于静态网页的根目录,访问时不需加路径。(图片,js,css)

 http://localhost:3000/test.html

 http://localhost:3000/images/img.jpg

 views: 服务器端模块或模板文件。

 routes: 路由处理器,处理浏览器发出不同url的处理程序。动态网页的目录

 ----------------------------------------------------------------------------------

 app.js 主模块文件,是总路由,分支路由写在routes目录下

 package.json 包管理,依赖包

 //引入系统和第三方模块

 var express = require('express');

 var path = require('path');

 var favicon = require('serve-favicon');

 var logger = require('morgan');

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

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

 //引入路由

 var index = require('./routes/index');

 var users = require('./routes/users');

 var vipCenter=require("./routes/vip");

 //实例化express框架

 var app = express();

 // view engine setup

 //设置模板的默认目录

 app.set('views', path.join(__dirname, 'views'));

 //设置ejs为模板引擎

 app.set('view engine', 'ejs');

 // uncomment after placing your favicon in /public

 //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));

 //中间件

 app.use(logger('dev'));

 app.use(bodyParser.json());

 app.use(bodyParser.urlencoded({ extended: false }));

 app.use(cookieParser());

 //设置静态目录为public

 app.use(express.static(path.join(__dirname, 'public')));

 //使用分路由

 app.use('/', index);

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

 app.use("/vip",vipCenter);

 // catch 404 and forward to error handler

 //404找不到

 app.use(function(req, res, next) {

 var err = new Error('Not Found');

 err.status = 404;

 next(err);

 });

 // error handler

 //错误

 app.use(function(err, req, res, next) {

 // set locals, only providing error in development

 res.locals.message = err.message;

 res.locals.error = req.app.get('env') === 'development' ? err : {};

 // render the error page

 res.status(err.status || 500);

 res.render('error');

 });

 //导出模块

module.exports = app;

4. Express路由(重点)

路由是指如何定义应用的端点(URIs)以及如何响应客户端的请求。
路由是由一个 URI、HTTP 请求(GET、POST等)和若干个句柄(函数)组成,它的结构如下: app.METHOD(path, [callback...], callback), app 是 express 对象的一个实例, METHOD 是一个 HTTP 请求方法, path 是服务器上的路径, callback 是当路由匹配时要执行的函数。

4.1. 基础用法

var express = require('express');

var app = express();

//设置请求路径“/”对应的处理器

app.get('/', function(req, res) {

 res.send('hello world');

});

4.2. 路由方法

路由与HTTP 请求方法(GET、POST)相关联。
为应用“/”路径定义的 GET 和 POST 请求:

// 处理get请求方式,超链接、浏览器地址栏直接访问

app.get('/', function (req, res) {

 res.send('处理get请求');

});

// 处理post请求方式,表单提交

app.post('/', function (req, res) {

 res.send('处理post请求');

});

app.all() 是一个特殊的路由方法,没有任何 HTTP 方法与其对应,它的作用是对于一个路径上的所有请求加载中间件。 all相当于既可以处理GET,也可以处理POST。

app.all('/, function (req, res, next) {

 res.send('任意方式的请求');

});

4.3. Router(重点中的重点)

express.Router类可以创建模块化(独立的)、可挂载的路由对象。Router对象是一个完整的中间件和路由系统,因此常称其为一个 “mini-app”。

1、新建一个模块vip.js(express项目要求我们放到routes

var express = require('express');

var router = express.Router();

// 定义模块的主页的路由

router.get('/', function(req, res) {

 res.send('vip首页');

});

// 定义模块“/getScore”路径的路由

router.get('/getScore', function(req, res) {

 res.send('vip积分');

});

module.exports = router;

**2****、app.js** **使用**

var vip = require('./vip);

...

app.use('/vip', vip); // 路径“/vip”使用vip路由模块,这个行为就是把“vip”模块挂载到“/vip”路径下面。

访问

http://localhost:3000/vip/ //vip首页
http://localhost:3000/vip/getScore //vip积分

5. 响应对象(重点)

响应对象(res)的方法向客户端返回响应,终结请求响应的循环。如果在路由函数中一个方法也不调用,来自客户端的请求会一直挂起。

5.1. send方法(重点中的重点)

send(data) 可以返回任意类型数据。

res.send(new Buffer('whoop'));//流

res.send({ some: 'json' });// json数据

res.send('

some html

');//普通文本 //设置状态码,并且返回内容 res.status(404).send('Sorry, we cannot find that!'); res.status(500).send({ error: 'something blew up' });

5.2. json方法

json(data) 返回json对象,一般针对ajax应用。

res.json(null);

res.json({ user: 'tobi' });

//设置状态码,并返回json数据

res.status(500).json({ error: 'message' });

5.3. jsonp方法

jsonp(data) 返回json对象,一般针对ajax的跨域访问。

res.jsonp(null);

res.jsonp({ user: 'tobi' });

//设置状态码,并返回json数据

res.status(500).jsonp({ error: 'message' });

5.4. render视图模板

ejs模板的使用
index.ejs模板





 

 <%= title %>

 

 

 

 

 

<%= title %>

Welcome to <%= title %>

**index.js** **路由** var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); //将视图和数据合并后发送给客户端 }); module.exports = router;

5.5. download下载

//下载当前目录下面的xxx.doc文件,并且重命名为yyy.doc。

router.get('/down', function(req, res, next) {

 res.download("./downTest.doc","express使用说明.doc")

});

5.6. redirect重定向

 重定向到从指定的URL路径(浏览器地址变为设置的地址)

 router.get('/it', function(req, res, next) {

 res.redirect("http://www.baidu.cn");

});

5.7. 404报错页面制作

router.get('/err', function(req, res, next) {

 //res.status(404).send("出错了:文件没有找到!");

 res.status(404).render("error",{message:"很抱歉,您查看的宝贝不存在,可能已下架或者被转移。"});

});

error.ejs

<%= message %>

5.8. 完整api

1. res.app:同req.app一样

2. res.append():追加指定HTTP头

3. res.set()在res.append()后将重置之前设置的头

4. res.cookie(name,value [,option]):设置Cookie

opition: domain / expires / httpOnly / maxAge / path / secure / signed

5. res.clearCookie():清除Cookie

npm install cookie

var cookie=require("cookie");

res.cookie("username",username); // 设置cookie

req.cookies.名称 // 取值

res.clearCookie(‘名称’); // 清除指定名称的Cookie

手动清除cookie,设置》高级》清除浏览数据

router.get("/checkLogin",function(req,res,next){

 var username=req.cookies.username;

 if(username) {

 res.send(true);

 }

 else{

 res.send(false);

 }

});

6. res.download():传送指定路径的文件

7. res.get():返回指定的HTTP头

8. res.json():传送JSON响应

9. res.jsonp():传送JSONP响应

10. res.location():只设置响应的Location HTTP头,不设置状态码或者close response

11. res.redirect():设置响应的Location HTTP头,并且设置状态码302

12. res.send():传送HTTP响应

13. res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type

14. res.set():设置HTTP头,传入object可以一次设置多个头

15. res.status():设置HTTP状态码

16. res.type():设置Content-Type的MIME类型

6. 请求对象(重点)

req(request)对象包含了数一次请求中的所有据(http头信息、请求参数...)

6.1. 获取浏览器地址栏中的参数(重点中的重点)

语法: req.query.参数名;

比如:http://localhost:3000/user?name=007

 req.query.name;

  **搜索功能**

search.html?keywords=笔记本电脑&catetype=it数码

router.get('/search.html', function(req, res, next) {

 var keywords=req.query.keywords;

 var catetype=req.query.catetype;

 res.json({"关键词":keywords,"类别":catetype});

});

6.2. 获取表单提交的值(重点中的重点)

Post提交 req.body.参数名

Get提交 req.query.参数名;

**login.html** public静态文件

 

用户账号

登录密码


用户账号

登录密码

路由文件 router.get('/loginGet', function(req, res, next) { var username=req.query.username; var pwd=req.query.pwd; res.json({"账号":username,"密码":pwd}); }); router.post('/loginPost', function(req, res, next) { var username=req.body.username; var pwd=req.body.pwd; res.json({"账号":username,"密码":pwd}); });

6.3. 获取路由中的参数parameters

  京东的产品地址:[https://item.jd.com/5268701.html](https://item.jd.com/5268701.html)

 /product/9999

 router.get("/product/:id",function(req,res){

 var productID=req.params.id;

 res.send("产品的编号是:"+productID);

});

 parameter [pəˈræmɪtɚ] params [pəˈræms]

伪静态: 看起来是一个静态文件,但其实是动态的。好处可以方便搜索引擎收录

6.4. 获取ip地址

router.get('/home', function(req, res, next) {

 res.send("

我是首页homepage!!!

你的ip地址是:"+req.hostname+"_"+req.ip+"

"); });

6.5. 完整api

1. req.app:当callback为外部文件时,用req.app访问express的实例

2. req.baseUrl:获取路由当前安装的URL路径

3. req.body / req.cookies:获得「请求主体」/ Cookies

4. req.fresh / req.stale:判断请求是否还「新鲜」

5. req.hostname / req.ip:获取主机名和IP地址

6. req.originalUrl:获取原始请求URL

7. req.params:获取路由的parameters

8. req.path:获取请求路径

9. req.protocol:获取协议类型

10. req.query:获取URL的查询参数串

11. req.route:获取当前匹配的路由

12. req.subdomains:获取子域名

13. req.accpets():检查请求的Accept头的请求类型

14. req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages

15. req.get():获取指定的HTTP请求头

16. req.is():判断请求头Content-Type的MIME类型

7. 中间件(了解)

Express 是一个自身功能极简,完全是由路由中间件构成一个的 web 开发框架:从本质上来说,一个 Express 应用就是在调用各种中间件。

7.1. 中间件到底是什么

中间件(Middleware)本质就是一个函数,它可以访问请求对象(request object),响应对象(response object),和 web应用中处于请求-响应循环流程中的中间件,一般被命名为 next的变量。(next尾函数,执行下一个任务)

中间件的功能包括:
1.执行任何代码。
2.修改请求和响应对象。
3.终结请求-响应循环。
4.调用堆栈中的下一个中间件。
如果当前中间件没有终结请求-响应循环,则必须调用 next() 方法将控制权交给下一个中间件,否则请求就会挂起。

7.2. 应用级中间件

应用级中间件绑定到 app对象使用 app.use()和 app.METHOD(),其中, METHOD是需要处理的 HTTP请求的方法,例如 GET, PUT, POST等等,全部小写。

//最简单的中间件

app.js

var express = require('express');

var app = express();

…………………………. ………………………….

/*

* 中间件:

*  1\. 中间件是一个函数

*  2\. 中间件可以访问请求对象和响应对象

*  3\. 可以阻止请求继续执行,如果不阻止,可以调用尾函数 next()

 *

* 尾函数next:

*  1\. 在一个中间件中执行尾函数,就可以调用下一个中间件

*  2\. 如果不用调用尾函数,就阻止执行

*  3\. 在尾函数后面的代码会执行,并且是在尾函数调起的下一个中间件结束后才执行

 */

 app.use(function(req,res,next){

 console.log('111');

 next();

 console.log('222');

 });

 app.use(function(req,res,next){

 console.log('333');

 next();

 console.log('444');

 });

…………………………. ………………………….

module.exports = app;

7.3. 内置中间件

Express中只为我们提供了唯一一个中间件,其他的中间件需要安装。

下面的例子使用了 express.static中间件,其中的 options 对象经过了精心的设计。

var options =  {

 dotfiles:  'ignore',

 etag:  false,

 extensions:  ['htm',  'html'],

 index:  false,

 maxAge:  '1d',

 redirect:  false,

 setHeaders:  function  (res, path, stat)  {

 res.set('x-timestamp', Date.now());

  }}

app.use(express.static('public', options));

每个应用可有多个静态目录。

app.use(express.static('public'));

app.use(express.static('uploads'));

app.use(express.static('files'));

app.use(logger('dev')); //控制台日志显示的中间件

app.use(express.static(path.join(__dirname, 'public'))); //静态资源目录的中间件

7.4. 第三方中间件

通过使用第三方中间件从而为 Express 应用增加更多功能。
安装所需功能的 node 模块,并在应用中加载,可以在应用级加载,也可以在路由级加载。
Multer 翻译文档https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md

文件上传中间件的使用

fileUpload.html 静态页面

 

图片上传

index.js 路由 * npm i multer --save *

前端准备工作:

1、需要一个表单,表单里面必须有一个文件域
2、必须给form表单指定enctype="multipart/form-data" 属性。
3、提交按钮类型为submit。

** 后端:接收请求**

1:前端请求表单页面http://127.0.0.1/upload/
2:渲染模板,不需加载额外的数据。

** 教程:**

http://blog.csdn.net/CatieCarter/article/details/77841208

https://github.com/expressjs/multer

//引入文件模块

var fs = require("fs");

//引入上传中间件模块

var multer = require('multer');

//初始化上传目录,自定义本地保存的路径

//var upload = multer({ dest: './files/' }); //使用storage时不需要单独制定目录,storage中有目录设置

var uploadFolder='./public/files/'; //放入静态资源目录才能正常显示

// 通过storage的 filename 属性定制上传文件名称

var storage = multer.diskStorage({

 destination: function (req, file, cb) {

 cb(null, uploadFolder); // 保存的路径,备注:需要自己创建如果不存在会报错

 },

 filename: function (req, file, cb) {

 //将保存文件名设置为 前缀+时间戳+文件扩展名

 var extName=file.originalname.substring(file.originalname.lastIndexOf(".")); //.jpg

 cb(null, file.fieldname + '_' + new Date().getTime() + extName);

 }

});

// 通过 storage 选项来对 上传行为 进行定制化

var upload = multer({ storage: storage });

//文件上传的路由,upload.single("imgUpload")指定单个文件上传,上传框的名称为imgUpload

router.post('/upload',upload.single("imgUpload"), function(req, res, next) {

 var fileInfo = req.file; //multer会将文件的信息写到 req.file上

 console.log('文件类型:', fileInfo.mimetype);

 console.log('原始文件名:', fileInfo.originalname);

 console.log('文件大小:', fileInfo.size);

 console.log('文件保存路径:', fileInfo.path);

 //渲染图片显示的模板,直接获取文件存放的地址,显示时不需要public目录

 var filepath=fileInfo.path.toString().replace("public","");

 res.render("imgFileList.ejs",{imgShow: filepath});

 //直接显示出来

 res.set({"Content-Type":"text/html"});

 res.send("");

});

imgFileList.ejs 图片显示模板

 

 

图片上传展示

你可能感兴趣的:(Express框架)