概述

Express是目前最流行的基于Node.js的Web开发框架,可以快速地搭建一个完整功能的网站。

Express上手非常简单,首先新建一个项目目录,假定叫做hello-world。

$ mkdir hello-world

进入该目录,新建一个package.json文件,内容如下。

{"name": "hello-world","description": "hello world test app","version": "0.0.1","private": true,"dependencies": {"express": "4.x"}
}

上面代码定义了项目的名称、描述、版本等,并且指定需要4.0版本以上的Express。

然后,就可以安装了。

$ npm install

执行上面的命令以后,在项目根目录下,新建一个启动文件,假定叫做index.js。

var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(8080);

然后,运行上面的启动脚本。

$ node index

现在就可以访问http://localhost:8080,它会在浏览器中打开当前目录的public子目录(严格来说,是打开public目录的index.html文件)。如果public目录之中有一个图片文件my_image.png,那么可以用http://localhost:8080/my_image.png访问该文件。

你也可以在index.js之中,生成动态网页。

然后,在命令行下运行启动脚本,就可以在浏览器中访问项目网站了。

$ node index

上面代码会在本机的3000端口启动一个网站,网页显示Hello World。

启动脚本index.js的app.get方法,用于指定不同的访问路径所对应的回调函数,这叫做“路由”(routing)。上面代码只指定了根目录的回调函数,因此只有一个路由记录。实际应用中,可能有多个路由记录。

这时,最好就把路由放到一个单独的文件中,比如新建一个routes子目录。

然后,原来的index.js就变成下面这样。

// index.js
var express = require('express');
var app = express();
var routes = require('./routes')(app);
app.listen(3000);

运行原理

底层:http模块

Express框架建立在node.js内置的http模块上。http模块生成服务器的原始代码如下。

var http = require("http");
var app = http.createServer(function(request, response) {response.writeHead(200, {"Content-Type": "text/plain"});response.end("Hello world!");
});
app.listen(3000, "localhost");

上面代码的关键是http模块的createServer方法,表示生成一个HTTP服务器实例。该方法接受一个回调函数,该回调函数的参数,分别为代表HTTP请求和HTTP回应的request对象和response对象。

Express框架的核心是对http模块的再包装。上面的代码用Express改写如下。

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

比较两段代码,可以看到它们非常接近。原来是用http.createServer方法新建一个app实例,现在则是用Express的构造方法,生成一个Epress实例。两者的回调函数都是相同的。Express框架等于在http模块之上,加了一个中间层。

什么是中间件

简单说,中间件(middleware)就是处理HTTP请求的函数。它最大的特点就是,一个中间件处理完,再传递给下一个中间件。App实例在运行过程中,会调用一系列的中间件。

每个中间件可以从App实例,接收三个参数,依次为request对象(代表HTTP请求)、response对象(代表HTTP回应),next回调函数(代表下一个中间件)。每个中间件都可以对HTTP请求(request对象)进行加工,并且决定是否调用next方法,将request对象再传给下一个中间件。

一个不进行任何操作、只传递request对象的中间件,就是下面这样。

function uselessMiddleware(req, res, next) {next();
}

上面代码的next就是下一个中间件。如果它带有参数,则代表抛出一个错误,参数为错误文本。

function uselessMiddleware(req, res, next) {next('出错了!');
}

抛出错误以后,后面的中间件将不再执行,直到发现一个错误处理函数为止。

use方法

use是express注册中间件的方法,它返回一个函数。下面是一个连续调用两个中间件的例子。

var express = require("express");
var http = require("http");var app = express();app.use(function(request, response, next) {console.log("In comes a " + request.method + " to " + request.url);next();
});app.use(function(request, response) {response.writeHead(200, { "Content-Type": "text/plain" });response.end("Hello world!\n");
});http.createServer(app).listen(1337);

上面代码使用app.use方法,注册了两个中间件。收到HTTP请求后,先调用第一个中间件,在控制台输出一行信息,然后通过next方法,将执行权传给第二个中间件,输出HTTP回应。由于第二个中间件没有调用next方法,所以request对象就不再向后传递了。

use方法内部可以对访问路径进行判断,据此就能实现简单的路由,根据不同的请求网址,返回不同的网页内容。

var express = require("express");
var http = require("http");var app = express();app.use(function(request, response, next) {if (request.url == "/") {response.writeHead(200, { "Content-Type": "text/plain" });response.end("Welcome to the homepage!\n");} else {next();}
});app.use(function(request, response, next) {if (request.url == "/about") {response.writeHead(200, { "Content-Type": "text/plain" });} else {next();}
});app.use(function(request, response) {response.writeHead(404, { "Content-Type": "text/plain" });response.end("404 error!\n");
});http.createServer(app).listen(1337);

上面代码通过request.url属性,判断请求的网址,从而返回不同的内容。注意,app.use方法一共登记了三个中间件,只要请求路径匹配,就不会将执行权交给下一个中间件。因此,最后一个中间件会返回404错误,即前面的中间件都没匹配请求路径,找不到所要请求的资源。

除了在回调函数内部判断请求的网址,use方法也允许将请求网址写在第一个参数。这代表,只有请求路径匹配这个参数,后面的中间件才会生效。无疑,这样写更加清晰和方便。

app.use('/path', someMiddleware);

上面代码表示,只对根目录的请求,调用某个中间件。

因此,上面的代码可以写成下面的样子。

var express = require("express");
var http = require("http");var app = express();app.use("/home", function(request, response, next) {response.writeHead(200, { "Content-Type": "text/plain" });response.end("Welcome to the homepage!\n");
});app.use("/about", function(request, response, next) {response.writeHead(200, { "Content-Type": "text/plain" });response.end("Welcome to the about page!\n");
});app.use(function(request, response) {response.writeHead(404, { "Content-Type": "text/plain" });response.end("404 error!\n");
});http.createServer(app).listen(1337);

Express的方法

all方法和HTTP动词方法

针对不同的请求,Express提供了use方法的一些别名。比如,上面代码也可以用别名的形式来写。

var express = require("express");
var http = require("http");
var app = express();app.all("*", function(request, response, next) {response.writeHead(200, { "Content-Type": "text/plain" });next();
});app.get("/", function(request, response) {response.end("Welcome to the homepage!");
});app.get("/about", function(request, response) {response.end("Welcome to the about page!");
});app.get("*", function(request, response) {response.end("404!");
});http.createServer(app).listen(1337);

上面代码的all方法表示,所有请求都必须通过该中间件,参数中的“*”表示对所有路径有效。get方法则是只有GET动词的HTTP请求通过该中间件,它的第一个参数是请求的路径。由于get方法的回调函数没有调用next方法,所以只要有一个中间件被调用了,后面的中间件就不会再被调用了。

除了get方法以外,Express还提供post、put、delete方法,即HTTP动词都是Express的方法。

这些方法的第一个参数,都是请求的路径。除了绝对匹配以外,Express允许模式匹配。

app.get("/hello/:who", function(req, res) {res.end("Hello, " + req.params.who + ".");
});

上面代码将匹配“/hello/alice”网址,网址中的alice将被捕获,作为req.params.who属性的值。需要注意的是,捕获后需要对网址进行检查,过滤不安全字符,上面的写法只是为了演示,生产中不应这样直接使用用户提供的值。

如果在模式参数后面加上问号,表示该参数可选。

app.get('/hello/:who?',function(req,res) {if(req.params.id) {res.end("Hello, " + req.params.who + ".");}else {res.send("Hello, Guest.");}
});

下面是一些更复杂的模式匹配的例子。

app.get('/forum/:fid/thread/:tid', middleware)// 匹配/commits/71dbb9c
// 或/commits/71dbb9c..4c084f9这样的git格式的网址
app.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){var from = req.params[0];var to = req.params[1] || 'HEAD';res.send('commit range ' + from + '..' + to);
});

set方法

set方法用于指定变量的值。

app.set("views", __dirname + "/views");app.set("view engine", "jade");

上面代码使用set方法,为系统变量“views”和“view engine”指定值。

response对象

(1)response.redirect方法

response.redirect方法允许网址的重定向。

response.redirect("/hello/anime");
response.redirect("http://www.example.com");
response.redirect(301, "http://www.example.com");

(2)response.sendFile方法

response.sendFile方法用于发送文件。

response.sendFile("/path/to/anime.mp4");

(3)response.render方法

response.render方法用于渲染网页模板。

app.get("/", function(request, response) {response.render("index", { message: "Hello World" });
});

上面代码使用render方法,将message变量传入index模板,渲染成HTML网页。

requst对象

(1)request.ip

request.ip属性用于获得HTTP请求的IP地址。

(2)request.files

request.files用于获取上传的文件。

搭建HTTPs服务器

使用Express搭建HTTPs加密服务器,也很简单。

var fs = require('fs');
var options = {key: fs.readFileSync('E:/ssl/myserver.key'),cert: fs.readFileSync('E:/ssl/myserver.crt'),passphrase: '1234'
};var https = require('https');
var express = require('express');
var app = express();app.get('/', function(req, res){res.send('Hello World Expressjs');
});var server = https.createServer(options, app);
server.listen(8084);
console.log('Server is running on port 8084');

本文由博客群发一文多发等运营工具平台 OpenWrite 发布

Node组件——Express简介相关推荐

  1. Node.js Express 框架 Express

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

  2. Node.js—Express、Express 路由 、Express 中间件、使用 Express 写接口

    目标: 能够使用 express.static() 快速托管静态资源 能够使用 express 路由精简项目结构 能够使用常见的 express 中间件 能够使用 express 创建API接口 能够 ...

  3. 跟李宁老师做项目:小程序版网上商城(Node.js + Express + MySQL)-李宁-专题视频课程...

    跟李宁老师做项目:小程序版网上商城(Node.js + Express + MySQL)-8799人已学习 课程介绍         本课程采用的技术包括小程序开发.Node.js.Express和M ...

  4. node、express框架

    前面的话 Express是一个简洁.灵活的 node.js Web 应用开发框架, 它提供一系列强大的特性,帮助开发者创建各种 Web 和移动设备应用.本文将详细介绍express框架 概述 官网对E ...

  5. 基于Node+Vue+Express开发实现商城系统

    项目编号:BS-QD-006 前言: 2003年中国电子商城进入低谷期,在绝大多数人选择放弃电子商城的情况下,依旧有些企业仍未放弃,并苦苦坚持电子商城的发展.这使得人们不得不重新考虑如何定位新一代的电 ...

  6. 0040__node.js中Express简介

    node.js中Express简介_node express_包小志的博客-CSDN博客

  7. 【node】express中mysql的基本用法、连接池的使用、事务的回滚

    [node]express中mysql的基本用法.连接池的使用 安装mysql包 mysql的配置信息 mysql基本操作 查询mysql并渲染数据 mysql插入操作 首先在html页面写上< ...

  8. kaptcha验证码组件使用简介

    kaptcha验证码组件使用简介 Kaptcha是一个基于SimpleCaptcha的验证码开源项目. 官网地址:http://code.google.com/p/kaptcha/ kaptcha的使 ...

  9. TWaver HTML5 + Node.js + express + socket.io + redis(六)

    接上一篇TWaver HTML5 + Node.js + express + socket.io + redis(五), 这一篇将讲解如何用模版生成html页面, 如何验证用户登录, 您将了解到: 1 ...

最新文章

  1. ASP.NET-Cookies的用法
  2. PHP06 PHP操作MySQL
  3. Taro+react开发(97):问答模块04
  4. 聊聊zxing的qrcode
  5. window系统对应默认IE浏览器版本
  6. python slice和列表切割_Python 列表切边 slice
  7. echarts实现2d柱状_记录echarts比较难实现的图1(一个背景上呈现三个柱状图)
  8. ABSynthe : 侧信道攻击加密函数窃取密钥
  9. Java 的三种 Base64
  10. 开源IT监控系统对比
  11. Vue echarts 修改 X轴、Y轴 样式以及文字样式
  12. 无版权素材网站,免费、可商用
  13. 【渝粤教育】广东开放大学 建设工程法规 形成性考核 (32)
  14. python四位数字加密_python实现字符串加密成纯数字
  15. 摄影口诀--针对不同情景
  16. 文献阅读_国内外旅游在线评论研究综述(中文文献)
  17. 关于word插入题注“题注或页码中不含章节号”错误提示
  18. 乌镇、世博、上海游之西、东栅
  19. react入门-列表渲染(动态获取数据)
  20. 千呼万唤,小灰的新书出版了!

热门文章

  1. 如何在javascript中解析带有两个小数位的浮点数?
  2. elasticsearch 关联查询_Elasticsearch字段类型之Range经典应用场景
  3. Gitlab 服务器搭建,maven安装与jdk安装,linux下安装git
  4. java实现增量更新_Android 增量更新的完整实现步骤
  5. java vo转map_Java后端必备的开发规范
  6. python len函数_你需要了解的最重要的Python概念
  7. 在android中使用opencv,在安卓上使用OpenCV的指南 - kdnuggets
  8. 用c 语言写出五子棋的代码,C语言案例:控制台版本的五子棋游戏【代码】
  9. ❤️六万字《SpringMVC框架介绍—从入门到高级》(建议收藏)❤️
  10. 结构体08:结构体案例2