浅谈Node.js轻量级Web框架Express4.x使用指南


Posted in Javascript onMay 03, 2017

Express是一个轻量级的Web框架,简单、灵活

也是目前最流行的基于Nodejs的Web框架

通过它我们可以快速搭建功能完整的网站 (express 英文意思:特快列车)

Express现在是4.x版本,更新很快,并且不兼容旧版本,导致现在市面上很多优秀的Node书籍过时

这篇文章是一篇入门级的Express使用,需要一定Node.js的基础

Web应用创建

首先要做的是下载express并引用

npm install express --save

全局安装就+个-g

引用express

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

通过app我们就可以使用各种express的API

在3.x版本的时候是这样写的

var app =express.createServer();

现在这个函数已经被抛弃了

下面正式创建应用

//app.js
var express = require('express');
var app = express();
app.get('/', function(req, res){
 res.send('Express');
});
app.listen(3000);

启动之后就能给够在页面看到效果

$ node app.js

浅谈Node.js轻量级Web框架Express4.x使用指南

app.get()

上面的app.listen()就不多说了

用于监听端口

app.get(path, function(req, res){ })

用于用于处理客户端向服务器发送的GET请求

path表示请求的路径

回调函数的req和res是request和response的意思

request表示客户端发送的HTTP请求信息

response表示服务器发送的HTTP响应信息

使用res.send()可以向客户端发送信息

//app.js
var express = require('express');
var app = express();

app.get('/', function(req, res){
 res.send('<h1>Express</h1>');
});
app.get('/demo', function(req, res){
 res.send('<h1>Demo</h1>');
})
app.get('/*', function(req, res){
 res.send('<h1>404<h1>');
})

app.listen(3000);
 

浅谈Node.js轻量级Web框架Express4.x使用指南

浅谈Node.js轻量级Web框架Express4.x使用指南

app.post()

app.post(path, function(req, res){ })

用于用于处理客户端向服务器发送的POST请求

和GET请求不同,POST请求不会将信息放在url中

而是写入请求头中

它的解析有所不同,下面再说

app.all()

在此之前还要提一个概念——中间件

Middleware中间件在不同环境下有不同含义

而在我们express中,简单说它就是一个特殊的函数

用来处理HTTP请求的函数

并且它有一个特点——处理完一个中间件可以传递给下一个中间件来处理

funciton(req, res, next){
  ...
  next();
}

(如果不使用执行next函数,那么之后监听的函数也不会执行)

可以向next中传递字符串参数,代表抛出的错误信息

这样当数据往下传递的时候,中间件不再进行处理

直到找到一个错误处理函数为止

app.all(path, function(req, res, next){ })的使用中

就需要我们定义这样的中间件

这个方法可以过滤所有路径上的请求

换句话说,在其他所有的中间件处理之前

必须先通过app.all()的中间件进行处理

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

app.all('*', function(req, res, next){
 res.writeHead(200, ':)');
 next();
});

app.get('/', function(req, res){
 res.end('<h1>Express</h1>');
});
app.get('/demo', function(req, res){
 res.end('<h1>Demo</h1>');
})
app.get('/*', function(req, res){
 res.end('<h1>404<h1>');
})

app.listen(3000);

这样不论客户端向我们发出了什么样的路径请求

服务器响应信息前都会先打上响应头

app.use()

app.use([path, ]function(req, res, next){ })

这个方法一般情况是用来调用中间件的

与前面的函数不同,它的第一个path参数可以省略,默认'/'

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

上面的这个用法就是指定静态文件的访问路径

通过next参数我们可以连续调用中间件函数

app.use(function(req, res, next){
 console.log(1);
 next();
});
app.use(function(req, res, next){
 console.log(2);
 next();
});
app.use(function(req, res, next){
 console.log(3);
});
app.use(function(req, res, next){
 console.log(4);
});

当发出网络请求的时候

控制台就会输出 1 2 3

因为第三个中间件没有调用next方法

所以处理到此为止

不会输出4

app.use()除了调用中间件

还可以根据请求路径的不同,返回不同信息

但我们一般不会这么用

//app.js
var express = require('express');
var app = express();

app.use(function(req, res, next){
 if(req.url == '/'){
  res.end('<h1>Express</h1>');
 }else{
  next();
 }
});
app.use(function(req, res, next){
 if(req.url == '/demo'){
  res.end('<h1>Demo</h1>');
 }else{
  next();
 }
});
app.use(function(req, res, next){
 res.end('<h1>404<h1>');
});

app.listen(3000);

请求与响应

上面express中每一个回调函数都不可缺少req和res参数

重要性可见一斑

常见的req与res中的属性/方法如下(原生node.js的req、res属性/方法也可以使用)

Request对象:

API 含义
req.app 当callback为外部文件时,用于访问express的实例
req.baseUrl 获取路由当前安装的URL路径
req.body/cookies 获得「请求主体」/ Cookies
req.fresh/stale 判断请求是否还「新鲜」
req.hostname/ip 获取主机名和IP地址
req.originalUrl 获取原始请求URL
req.params 获取路由的parameters
req.path 获取请求路径
req.protocol 获取协议类型
req.query 获取URL的查询参数串
req.route 获取当前匹配的路由
req.subdomains 获取子域名
req.acceptsCharsets 返回指定字符集的第一个可接受字符编码
req.acceptsEncodings 返回指定字符集的第一个可接受字符编码
req.acceptsLanguages 返回指定字符集的第一个可接受字符编码
req.accepts() 检查可接受的请求的文档类型
req.get() 获取指定的HTTP请求头
req.is() 判断请求头Content-Type的MIME类型

Response对象:

API 含义
res.app 同req.app
res.append() 追加指定HTTP头
res.set() 在res.append()后将重置之前设置的头
res.cookie() 设置Cookie
res.clearCookie() 清除Cookie
res.download() 传送指定路径的文件
res.get() 返回指定的HTTP头
res.json() 传送JSON响应
res.jsonp() 传送JSONP响应
res.location() 只设置响应的Location HTTP头,不设置状态码或者close response
res.redirect() 设置响应的Location HTTP头,并且设置状态码302
res.send() 传送HTTP响应
res.sendFile() 传送指定路径的文件 -会自动根据文件extension设定Content-Type
res.set() 设置HTTP头,传入object可以一次设置多个头
res.status() 设置HTTP状态码
res.type() 设置Content-Type的MIME类型

挑一些重点

req.query

req.query可以获取请求路径参数的对象

向服务器发送请求 http://localhost:3000/?user=tester&pass[a]=123&pass[b]=456

//app.js
var express = require('express');
var app = express();

app.get('/', function(req, res, next){
 console.log(req.query);
 console.log(req.query.user); //tester
 console.log(req.query.pass.a); //123
 console.log(req.query.pass.b); //456
 res.end();
});

app.listen(3000);

req.params

req.params可以解析复杂路由规则上的属性
(req.param综合了req.query和req.param的功能,但是被移除了不要使用)

向服务器发送请求 http://localhost:3000/123456

//app.js
var express = require('express');
var app = express();

app.get('/:id', function(req, res, next){
 console.log(req.params.id); //123456
 res.end();
});

app.listen(3000);

 这样不论我在根路径后输入的是什么

都会被解析为req.params.id

res.send()

res.send用于向客户端响应信息 并且它的强大之处在于可以智能的处理我们传递的不同类型参数

app.get('/', function(req, res, next){
 res.send('express');
});

当参数为字符串,会将响应头Content-Type默认设置为text/html

也就是解析为html呈现在我们的页面上

app.get('/', function(req, res){
 res.send(200);
});

当参数为数字,会自动帮我们设置响应体(状态码…)

app.get('/', function(req, res){
 res.send([1, 2, 3]);
});

当参数为数组或对象,它会响应一个JSON

res.redirect()

使用这个方法可以让我们对网页重定向

比如使用绝对url跳转到不同的域名

app.get('/', function(req, res){
 res.redirect('http://www.baidu.com');
});

res.redirect()默认响应状态码是302

可以更改这个状态码作为res.redirect()的第一个参数

//app.js
var express = require('express');
var app = express();

app.get('/', function(req, res){
 res.redirect(302, 'demo');
});
app.get('/demo', function(req, res){
 res.end();
});

app.listen(3000);

当在url地址栏中输入http://localhost:3000

页面就会重定向到http://localhost:3000/demo

静态资源

静态资源就是指我们在开发中用到的css、js、img等等

它们需要存放到一个静态资源目录

当浏览器发出了一个非HTML文件请求

服务器就会从这个静态资源目录下去查找文件

我们一般在根目录下创建一个public文件来存储

并在public中创建stylesheets、javascripts、images等文件夹

用来存储特定类型的资源

指定静态资源目录的方法上面已经提到了

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

比如说我们的html中有这样的代码

<link href="/javascripts/jquery.js" rel="external nofollow" rel="stylesheet" media="screen">

那么客户端运行发出请求

服务器就会在public的javascripts文件夹下找到jQuery.js静态资源

模板引擎

express框架默认是ejs和jade渲染模板

这里以jade为例

使用时肯定要下载

npm install jade --save

再通过app.set()指定查找模板文件的目录(类似于静态资源)

并指定模板文件后缀为jade

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

(如果不使用模板而使用原生html,app.set('view engine', 'html');)

如果我们想要访问模板该怎么做呢?

很简单,只需要一个方法res.render()

浅谈Node.js轻量级Web框架Express4.x使用指南

现在我写了一个简单的jade模板(关于jade语法超出本文讨论范围)

//views/index.jade
doctype html
html
 head
  title= title
  link(rel='stylesheet', href='/stylesheets/style.css')
 body
  h1= title
  p= content

通过res.render渲染

//app.js
var express = require('express');
var path = require('path');
var app = express();

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

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

app.get('/', function(req, res){
 res.render('index', {
  title: 'Express',
  content: 'this is an example'
 });
});

app.listen(3000);

浅谈Node.js轻量级Web框架Express4.x使用指南

res.render()

res.render(view[, datas][, callback])

用于对网页模板进行渲染

第一个参数是要渲染的模板名称

第二个参数是传递给模板的变量,以对象形式存储,没有可省略

第三个参数是渲染后回调函数,可以省略

路由

路由的意思就是根据不同的路径,来指定不同的处理方法

我们一般把不同的路由封装进不同的模块

首先在根目录下创建一个文件夹routes存储路由

现在我在routes文件夹下创建俩个路由文件index.js和users.js

浅谈Node.js轻量级Web框架Express4.x使用指南

修改app.js

//app.js
var express = require('express');
var path = require('path');
var app = express();

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

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

app.listen(3000);

这样表示http://localhost:3000/的路由交给index处理

http://localhost:3000/users的路由交给users处理

下面简单的实现一下路由

//routes/index.js
var express = require('express');
var router = express.Router();

router.get('/', function(req, res){
 res.end('index');
});

router.get('/123', function(){
 res.end(123);
});

module.exports = router;
//routes/users.js
var express = require('express');
var router = express.Router();

router.get('/', function(req, res) {
 res.end('users');
});

module.exports = router;

通过express.Router()创建的router就像一个mini版的app一样

app能做的,router都能做

只是我们把逻辑都封装到了各个路由模块中

上面代码的结果:

浅谈Node.js轻量级Web框架Express4.x使用指南

浅谈Node.js轻量级Web框架Express4.x使用指南

浅谈Node.js轻量级Web框架Express4.x使用指南

body-parser中间件

作为一个入门级文章

最后就来浅显的谈一个中间件body-parser吧

其实express在3.x版本中内置了很多中间件

但是4.x版本就将出static以外的所有中间件全部抽离出来了

所以就需要我们单独安装

对照表如下:

Express 3.0 Express 4.0
bodyParser body-parser
compress compression
cookieSession cookie-session
logger morgan
cookieParser cookie-parser
session express-session
favicon static-favicon
response-time response-time
error-handler errorhandler
method-override method-override
timeout connect-timeout
vhost vhost
csrf csurf

刚才就提到了POST请求有所不同

不同的地方就在于我们需要body-parser这个中间件来处理数据

通过req.body来获得数据

首先使用前不要忘记下载

npm install body-parser --save
//app.js
var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var app = express();

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

app.get('/', function(req, res){
 res.send('<form method="POST" action="./form">\
       <input type="text" name="user">\
       <input type="submit">\
      </form>');
});
app.post('/form', function(req, res){
 console.log(req.body);
 var user = req.body.user;
 res.send('账号: ' + user);
});

app.listen(3000);

下面这四个方法分别用于对body内容采取不同的处理方法

  1. bodyParser.json(options) 处理JSON数据
  2. bodyParser.raw(options) 处理buffer数据
  3. bodyParser.text(options) 处理文本数据
  4. bodyParser.urlencoded(options) 处理UTF-8编码数据

这样我首先通过get请求获取主页面

浅谈Node.js轻量级Web框架Express4.x使用指南

提交表单向服务器发送post请求

浅谈Node.js轻量级Web框架Express4.x使用指南

服务器响应结果

express-generator

通过express-generator应用生成器

可以为我们快速生成项目雏形

在你要生成项目的目录中下载express-generator

npm install express-generator

然后输入

express <项目文件名>

这样express就会把必要的文件夹以及代码快速生成了

浅谈Node.js轻量级Web框架Express4.x使用指南

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
html组件不可输入(只读)同时任何组件都有效
Apr 01 Javascript
javascript:FF/Chrome与IE动态加载元素的区别说明
Jan 26 Javascript
20个实用的JavaScript技巧分享
Nov 28 Javascript
详解javascript表单的Ajax提交插件的使用
Dec 29 Javascript
微信小程序 Nginx环境配置详细介绍
Feb 14 Javascript
jQuery使用EasyUi实现三级联动下拉框效果
Mar 08 Javascript
iscroll.js滚动加载实例详解
Jul 18 Javascript
JS实现基本的网页计算器功能示例
Jan 16 Javascript
使用Vue 自定义文件选择器组件的实例代码
Mar 04 Javascript
如何通过vscode运行调试javascript代码
Jul 24 Javascript
vue+echarts实现动态折线图的方法与注意
Sep 01 Javascript
Bootstrap FileInput实现图片上传功能
Jan 28 Javascript
vue的Virtual Dom实现snabbdom解密
May 03 #Javascript
JavaScript中undefined和null的区别
May 03 #Javascript
Node.js对MongoDB数据库实现模糊查询的方法
May 03 #Javascript
xmlplus组件设计系列之文本框(TextBox)(3)
May 03 #Javascript
利用Mongoose让JSON数据直接插入或更新到MongoDB
May 03 #Javascript
xmlplus组件设计系列之选项卡(Tabbar)(5)
May 03 #Javascript
javascript过滤数组重复元素的实现方法
May 03 #Javascript
You might like
浏览器预览PHP文件时顶部出现空白影响布局分析原因及解决办法
2013/01/11 PHP
ubuntu下编译安装xcache for php5.3 的具体操作步骤
2013/06/18 PHP
PHP获取QQ达人QQ信息的方法
2015/03/05 PHP
php使用file函数、fseek函数读取大文件效率对比分析
2016/11/04 PHP
PHP守护进程化在C和PHP环境下的实现
2017/11/21 PHP
JavaScript中也使用$美元符号来代替document.getElementById
2010/06/19 Javascript
Javascript之this关键字深入解析
2013/11/12 Javascript
jquery改变disabled的boolean状态的三种方法
2013/12/13 Javascript
jQuery实现流动虚线框的方法
2015/01/29 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
jquery根据td给相同tr下其他td赋值的实现方法
2016/10/05 Javascript
vue组件中点击按钮后修改输入框的状态实例代码
2017/04/14 Javascript
JavaScript实现获取用户单击body中所有A标签内容的方法
2017/06/05 Javascript
Vue2.0父组件与子组件之间的事件发射与接收实例代码
2017/09/19 Javascript
javascript 数组精简技巧小结
2020/02/26 Javascript
Js实现复选框的全选、全不选反选功能代码实例
2020/02/28 Javascript
js实现微信聊天效果
2020/08/09 Javascript
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
初步解析Python下的多进程编程
2015/04/28 Python
Python基于hashlib模块的文件MD5一致性加密验证示例
2018/02/10 Python
python 实现得到当前时间偏移day天后的日期方法
2018/12/31 Python
对python:循环定义多个变量的实例详解
2019/01/20 Python
linux 下python多线程递归复制文件夹及文件夹中的文件
2020/01/02 Python
Python如何截图保存的三种方法(小结)
2020/09/01 Python
非常漂亮的CSS3百叶窗焦点图动画
2016/02/24 HTML / CSS
html5指南-6.如何创建离线web应用程序实现离线访问
2013/01/07 HTML / CSS
美国最大网上鞋店:Zappos
2016/07/25 全球购物
Kent & Curwen:与大卫·贝克汉姆合作
2017/06/13 全球购物
社会实践活动总结范文
2014/07/03 职场文书
幼儿园大班开学寄语
2014/08/02 职场文书
2014年初三班主任工作总结
2014/12/05 职场文书
2016年感恩节寄语
2015/12/07 职场文书
《称赞》教学反思
2016/02/17 职场文书
关于销售人员的年终工作总结要点
2019/08/15 职场文书
Pytorch 如何加速Dataloader提升数据读取速度
2021/05/28 Python
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
2022/02/12 Redis