NodeJs的好基友Express的详细介绍教程

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

使用 Express 可以快速地搭建一个完整功能的网站。

Express 框架核心特性:

  • 可以设置中间件来响应 HTTP 请求。

  • 定义了路由表用于执行不同的 HTTP 请求动作。

  • 可以通过向模板传递参数来动态渲染 HTML 页面。

先看下大概是啥样子的

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

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

var server = app.listen(8081, function () {

var host = server.address().address
var port = server.address().port

console.log("应用实例,访问地址为 http://%s:%s", host, port)

})

~~~

1. Express介绍 #

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

丰富的 HTTP 快捷方法和任意排列组合的 Connect 中间件,让你创建健壮、友好的 API 变得既快速又简单。

性能:Express 不对 Node.js 已有的特性进行二次抽象,我们只是在它之上扩展了 Web 应用所需的基本功能。

  • 模板解析
  • 静态文件服务
  • 中间件
  • 路由控制

还可以使用其他模块来帮助你创建各种Web和移动设备应用

2. 使用express #

本地安装

$ npm install express

获取、引用
通过变量app我们就可以调用express的各种方法

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

app.listen(3000);

思考: express的本质上是什么,是如何工作的

3. get请求 #

根据请求路径来处理客户端发出的GET请求
语法

app.get(path,function(request, response));
  • 第一个参数path为请求的路径
  • 第二个参数为处理请求的回调函数,有两个参数分别是
    • request 代表请求信息
    • response 代表响应信息
var express = require('express');
var app = express();
app.get('/',function(req,res){
    res.end('welcome to  首页');
});
app.get('/about',function(req,res){
 res.end('欢迎来到关于我们');
})
app.listen(3000);

4.curl客户端使用方法 #

  • 指定请求头
    curl -H 'content-type:application/json;charset=utf-8' http://localhost:8080/users
    
  • 指定方法名
    curl -X POST http://localhost:8080/users
    
  • 指定请求体
    curl --data "name=zfpx&age=8" http://localhost:8080/users
    

5. all #

app.all()函数可以匹配所有的HTTP动词
路由中的星号能匹配所有的路径
语法

app.all(path,function(request, response));

示例

var express = require('express');//引入express
var app = express();
app.all("*",function(req,res){
 res.send("404");
})
app.listen(3000);

5.1 练习: #

  1. 访问 /signup 返回字段符串 “注册”
  2. 访问 /signin 返回字段符串 “登录”
  3. 访问 /signout 返回字段符串 “退出”
  4. 访问其它路径,返回字符串 “你访问的路径不存在”

6. 获取请求参数 #

  • req.host 返回请求头里取的主机名(不包含端口号)
  • req.path 返回请求的URL的路径名
app.get('/',function(req,res){
   res.end('欢迎来到首页'+req.host+" "+req.path);
});

7.获得查询字符串 #

//http://localhost:3000/?a=1&b=2&c=3
app.get('/',function(req,res){
   res.send(req.query);
});

8. params路径参数 #

req.params可以用来获取请求URL中的参数值

app.get('/:id/:name',function(req,res){
   res.send(req.params.id+" "+req.params.name);
});

9. 中间件 #

中间件就是处理HTTP请求的函数,用来完成各种特定的任务
比如检查用户是否登录、检测用户是否有权限访问等,它的特点是:

  • 一个中间件处理完请求和响应可以把相应数据再传递给下一个中间件
  • 回调函数的next参数,表示接受其他中间件的调用,函数体中的next(),表示将请求数据传递给下一个中间件
  • 还可以根据路径来区分进行返回执行不同的中间件
var express = require('express');
var app = express();
var path = require('path');

app.use(function(req,res,next){
 res.setHeader('Content-Type','text/plain;charset=utf-8');
 next();
});

app.get('/',function(req,res){
 res.end('首页');
});
app.get('/about',function(req,res){
 res.end('关于我们');
});

app.listen(3000);

9.1 练习: #

编写一个请求日志中间件,不管客户端访问什么路径,都在控制台打印出
方法名 路径

10. send #

send方法向浏览器发送一个响应信息,并可以智能处理不同类型的数据
并在输出响应时会自动进行一些设置,比如HEAD信息、HTTP缓存支持等等。
语法

res.send([body|status], [body])

示例
1.当参数为一个String时,Content-Type默认设置为”text/html”。

res.send('Hello World'); //Hello World

2.当参数为Array或Object时,Express会返回一个JSON

res.send({ user: 'tobi' }); //{"user":"tobi"}
res.send([1,2,3]); //[1,2,3]

3.当参数为一个Number时,并且没有上面提到的任何一条在响应体里,Express会帮你设置一个响应体,比如:200会返回字符”OK”

res.send(200); // OK
res.send(404); // Not Found
res.send(500); // Internal Server Error

11.模板 #

在nodejs中使用express框架,它默认的是ejs和jade渲染模板

11.1 安装模板 #

npm install ejs

11.2 使用模板 #

使用ejs模板

//指定渲染模板文件的后缀名为ejs
app.set('view engine', 'ejs');
app.set('views',path.join(__dirname,'views'));
res.render('index');

模板使用html后缀

// 修改模板文件的后缀名为html
app.set( 'view engine', 'html' );
app.set('views',path.join(__dirname,'views'));
// 运行ejs模块
app.engine( '.html', require( 'ejs' ).__express ); //__express是ejs模块的一个公共属性,表示要渲染的文件扩展名

11.3 渲染视图 #

语法

  • 参数view就是模板的文件名
  • 在渲染模板时locals可为其模板传入变量值
  • callback用来处理返回的渲染后的字符串
res.render(view, [locals], callback);

11.4 模板原理 #

var tmpl = '<h1>{{name}}</h1><h1>{{age}}</h1>';
var data = {name:'zfpx',age:30};
var html= tmpl.replace(/\{\{(\w+)\}\}/g,function(input,group){
    return data[group];
})

console.log(html);

12. 静态文件服务器 #

如果要在网页中加载静态文件(css、js、img),就需要另外指定一个存放静态文件的目录,当浏览器发出非HTML文件请求时,服务器端就会到这个目录下去寻找相关文件

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

13. 重定向 #

redirect方法允许网址的重定向,跳转到指定的url并且可以指定status,默认为302方式。
语法

res.redirect([status], url);

示例

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

14. post请求 #

post方法 根据请求路径来处理客户端发出的Post请求
语法

app.post(path,function(req, res));

示例

var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:true}));
app.post('/login',function(req,res){
        console.log(req.body.username);
});

15. 作业: 注册登陆实战 #

实现一个注册登录的功功,描述如下

  1. 客户端以GET方法访问 /signup ,会返回一个注册的包含用户名和密码两个字段的空白表单
  2. 填写这个空白表单,会向当前路径提交post请求,提交到后台后把此用户名和密码保存到用户数组里,然后重定向到登录页
  3. 在登录页,填写用户名和密码,如果输入正确跳转到欢迎页,如果填写不正确返回登录页。

16. 中间件原理 #

// 当请求到来的时候执行app,这是会对数组里的配置项一次匹配,匹配上的执行,匹配不上执行
var app = function(req,res){
   var i=0;//定义一个变量每次执行next后加一
    //每执行一次next,会取出一个中间件函数执行,并且把next传进去
   function next(){
       var fn = app.routes[i++];
       if(fn)
        fn(req,res,next);
   }
    next();
}
//存放中间件函数的数组
app.routes = [];
//配置函数
app.use = function(fn){
    //往数组里添加函数
    app.routes.push(fn);
}
//------------------------
app.use(function(req,res,next){
    console.log(req.url);
    console.log(1);
    next();
});
app.use(function(req,res,next){
    console.log(2);
    res.end('ok');
    next();
});
//-------------------
var http = require('http');
var server = http.createServer(app);
server.listen(9090);

17. params原理 #

//是路由里的路径
var path = '/users/:name/:age';
//真实请求的URL
var url = '/users/zfpx/8';
//存放所有的参数名
var paramNames = [];
var regStr = path.replace(/:(\w+)/g,function(matchedStr,group1){
    paramNames.push(group1);// name age 添加进来的
    return '(\\w+)';
});
console.log(regStr);//   \/users\/(\w+)\/(\w+)
var reg = new RegExp(regStr);
var result = url.match(reg);
//[ '/users/zfpx/8', 'zfpx', '8', index: 0, input: '/users/zfpx/8' ]
console.log(result);
var params = {};
//循环数组名 值就是 result中的分组
for(var i=0;i<paramNames.length;i++){
    params[paramNames[i]] = result[i+1];
}
console.log(params);

资源 #

从express源码中探析其路由机制

~

requestresponse 对象的具体介绍:

Request 对象 – request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。常见属性有:

  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.accepts():检查可接受的请求的文档类型
  14. req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
  15. req.get():获取指定的HTTP请求头
  16. req.is():判断请求头Content-Type的MIME类型

Response 对象 – response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据。常见属性有:

  1. res.app:同req.app一样
  2. res.append():追加指定HTTP头
  3. res.set()在res.append()后将重置之前设置的头
  4. res.cookie(name,value [,option]):设置Cookie
  5. opition: domain / expires / httpOnly / maxAge / path / secure / signed
  6. res.clearCookie():清除Cookie
  7. res.download():传送指定路径的文件
  8. res.get():返回指定的HTTP头
  9. res.json():传送JSON响应
  10. res.jsonp():传送JSONP响应
  11. res.location():只设置响应的Location HTTP头,不设置状态码或者close response
  12. res.redirect():设置响应的Location HTTP头,并且设置状态码302
  13. res.send():传送HTTP响应
  14. res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
  15. res.set():设置HTTP头,传入object可以一次设置多个头
  16. res.status():设置HTTP状态码
  17. res.type():设置Content-Type的MIME类型

我们已经了解了 HTTP 请求的基本应用,而路由决定了由谁(指定脚本)去响应客户端请求。

在HTTP请求中,我们可以通过路由提取出请求的URL以及GET/POST参数。

接下来我们扩展 Hello World,添加一些功能来处理更多类型的 HTTP 请求。

创建 express_demo2.js 文件,代码如下所示

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

// 主页输出 "Hello World"
app.get('/', function (req, res) {
console.log("主页 GET 请求");
res.send('Hello GET');
})


// POST 请求
app.post('/', function (req, res) {
console.log("主页 POST 请求");
res.send('Hello POST');
})

// /del_user 页面响应
app.get('/del_user', function (req, res) {
console.log("/del_user 响应 DELETE 请求");
res.send('删除页面');
})

// /list_user 页面 GET 请求
app.get('/list_user', function (req, res) {
console.log("/list_user GET 请求");
res.send('用户列表页面');
})

// 对页面 abcd, abxcd, ab123cd, 等响应 GET 请求
app.get('/ab*cd', function(req, res) {
console.log("/ab*cd GET 请求");
res.send('正则匹配');
})


var server = app.listen(8081, function () {

var host = server.address().address
var port = server.address().port

console.log("应用实例,访问地址为 http://%s:%s", host, port)

})

~~~

未经允许不得转载:WEB前端开发 » NodeJs的好基友Express的详细介绍教程

赞 (0)