一、引言
在自学node.js的过程中有一个非常重要的框架,那就是Express。它是一个基于NodeJs http模块而编写的高层模块,弥补http模块的繁琐和不方便,能够快速开发http服务器。这里,就要用Express创建一个Web服务器,用来深入的理解这个框架,并熟悉创建Web服务器的过程。
二、核心概念——中间件
Express 是一个自身功能极简,完全是由路由和中间件构成一个的 web 开发框架:从本质上来说,一个 Express 应用就是在调用各种中间件。
中间件(Middleware) 是一个函数,它可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为 next 的变量。
中间件的功能包括:
- 执行任何代码。
- 修改请求和响应对象。
终结请求-响应循环。调用堆栈中的下一个中间件。
如果当前中间件没有终结请求-响应循环,则必须调用 next() 方法将控制权交给下一个中间件,否则请求就会挂起。
Express 应用可使用如下几种中间件:
- 应用级中间件
- 路由级中间件
- 错误处理中间件
- 内置中间件
- 第三方中间件
使用可选则挂载路径,可在应用级别或路由级别装载中间件。另外,你还可以同时装在一系列中间件函数,从而在一个挂载点上创建一个子中间件栈。
app.use(url, ?(req, res, next)=>{//.....中间件要执行的代码next( ); ??//调用下一个中间件或路由
三、模块下载
因为创建Web服务器要用到第三方模块的mysql和Express,所以需要在创建新项目之后,在NPM中进行下载,安装这两个模块,具体过程如下:
- Webstorm创建新项目project,右键点击project
- show in Explorer 进入目标文件夹
- 按shift 同时点击右键,在空白面板处
- 在此处打开命令窗口
- >npm i mysql 等待下载
- >npm i express 等待下载
下载完成后,webstorm中新创建的project下会自动更新出一个node_modules目录,里面会有需要的mysql和Express。
四、引例说明
使用Express创建一个web服务器,可以向客户端提供一个 /index响应,内容是一个HTML页面,其中还使用一个index.css文件/index.js文件
<!DOCTYPE html><html><head lang="en"> ???<meta charset="UTF-8"> ???<title></title> ???<link rel="stylesheet" href="index.css"/></head><body> ??<h1>INDEX.HTML</h1> ??<script src="index.js"></script></body></html>
css文件和js文件此处省略
//app.js执行文件
const http = require(‘http‘);const express = require(‘express‘);var app = express();http.createServer(app).listen(8080);app.get(‘/index‘,(req,res)=>{ ???res.sendFile(__dirname+‘/pulic/index.html‘);});app.get(‘/index‘,(req,res)=>{ ???res.sendFile(__dirname+‘/pulic/index.css‘);});app.get(‘/index‘,(req,res)=>{ ???res.sendFile(__dirname+‘/pulic/index.js‘);});
小坑:如果index.html室友路由引入的,即使里面的index.css和index.js引入到了html中,若没有通过路由引入到app.js文件中,则这两个css与js文件是存在,但不响应的。所以,必须都通过路由引入到app.js文件中。但是,这同样会有一个问题,那就是如果要引入的文件太多,又必须要一个不漏的引入,那这样一个一个引太繁琐了,工作量太大,这就是中间件的重要性了,使用中间件可以方便快键的引入所需的所有文件。
Express 4.x官方还提供了一个中间件函数:app.use(express.static(‘public‘));//若客户端请求了/public目录下的某个资源,它可以直接向客户端返回,不会再调用后续的路由。
五、web服务器创建
要求:使用Express创建Web服务器应用,可以接收如下的请求:
1、编写SQL:创建数据库dangdang,书籍信息表book(bid,title,price,pubDate-出版日期,into-内容简介),并插入4行书籍记录。
2、至少可以向客户端提供如下静态资源:
/public/booklist.html 初始时显示一个空白的表格,页面加载完成后向服务器异步请求所有的书籍信息。
/public/jquery-1.11.3.js 在DIV中显示某一本书的详情
/public/book_detail.html 在DIV中显示某一本书的详情
/public/book_add.html 显示一个添加书籍的表单,点击“提交”按钮,异步提交给服务器
/public/book_update.html 显示一个修改书籍的表单,输入域中是当前要修改的书籍信息,点击“提交”按钮,异步提交给服务器。
3、以及如下动态资源地址——注意:下述地址都使用Ajax异步请求
GET /book 向客户端输出书籍表中的所有记录,以JSON格式
GET /book/:id 向客户端输出指定编号的书籍全部信息,以JSON格式
DELETE /book/:id 删除指定编号的书籍记录,向客户端输出{code:1,bid:xx}或者{code:2,msg:‘指定书籍编号不存在‘}
POST /book 接收客户端提交的请求主体数据(title/price/pubDate/intro),执行书籍添加操作保存入数据库,向客户端输出{code:1,bid:xx}
PUT /book 接收客户端提交的请求主体数据(bid/title/price/pubDate/intro),执行书籍更新操作修改数据库中对应的书籍,向客户端输出{code:1,affectRows:1}
实现:
DROP DATABASE IF EXISTS dangdang;CREATE DATABASE dangdang CHARSET=UTF8;USE dangdang;CREATE TABLE book( ?bid INT PRIMARY KEY AUTO_INCREMENT, ?title VARCHAR(64), ?price DECIMAL(8,2), ?pubDate BIGINT, ?intro VARCHAR(2048));INSERT INTO book VALUES(NULL, ‘西游记‘, ‘35.5‘, ‘1350123456789‘,‘描述了一个和尚和三个妖怪的故事‘),(NULL, ‘水浒传‘, ‘45.5‘, ‘1360123456789‘,‘描述了105个男人和3个女人的故事‘),(NULL, ‘红楼梦‘, ‘55.5‘, ‘1370123456789‘,‘描述了1个富二代的故事‘),(NULL, ‘三国志‘, ‘65.5‘, ‘1380123456789‘,‘描述了群雄争霸的故事‘);
//book_list.html<!DOCTYPE html><html><head lang="en"> ???<meta charset="UTF-8"> ???<title></title></head><body> ???<h1>书籍列表</h1> ???<hr/> ???<table border="1" width="100%"> ???????<thead> ???????????<tr> ???????????????<th>编号</th> ???????????????<th>书名</th> ???????????????<th>价格</th> ???????????????<th>出版日期</th> ???????????????<th>操作</th> ???????????</tr> ???????</thead> ???????<tbody> ????????????<td colspan="5">信息加载中....</td> ???????</tbody> ???</table> ???<script src="js/jquery-1.11.3.js"></script> ???<script> ???????//待当前页面加载完成,异步请求所有书籍信息 GET /book ???????$.ajax({ ???????????type:‘GET‘, ???????????url:‘/book‘, ???????????success:function(list){ ??????????????//遍历list数组,每个obj拼接为一个TR>TD*5,TBODY ??????????????var html =‘‘; ???????????????for(var book of list){ ???????????????????html +=` ???????????????????<tr> ?????????????????????<td>${book.bid}</td> ?????????????????????<td>${book.title}</td> ?????????????????????<td>${book.price}</td> ?????????????????????<td>${book.pubDate}</td> ?????????????????????<td> ????????????????????????<a class="detail" href="#">详情</a> ????????????????????????<a class="delete" href="#">删除</a> ????????????????????????<a class="update" href="#">修改</a> ?????????????????????</td> ???????????????????</tr> ???????????????????`; ???????????????} ???????????????$(‘tbody‘).html(html); ???????????} ???????}); ???</script></body></html>
//book_detail.html<!DOCTYPE html><html><head lang="en"> ???<meta charset="UTF-8"> ???<title></title> ???<style> ???????div { ???????????border-bottom: 1px solid #aaa; ???????????padding: 1em; ???????} ???</style></head><body><h1>书籍详情</h1><hr/><div id="bid"> ???<b>书籍编号:</b> ???<p>xxx</p></div><div id="title"> ???<b>书籍标题:</b> ???<p>xxx</p></div><div id="price"> ???<b>单价:</b> ???<p>xxx</p></div><div id="pubDate"> ???<b>出版日期:</b> ???<p>xxx</p></div><div id="intro"> ???<b>内容简介:</b> ???<p>xxx</p></div><script src="js/jquery-1.11.3.js"></script><script> ???//待页面加载完成,异步请求指定编号的书籍详情 ???//console.log(location); ???//console.log(location.search); ???//console.log(location.search.split(‘=‘)); ???var bid = location.search.split(‘=‘)[1]; ???$.ajax({ ???????type: ‘GET‘, ???????url: ‘/book/‘+bid, ???????success: function(book){ ???????????console.log(‘成功接收到服务器返回的书籍信息‘); ???????????console.log(book); ???????????$(‘#bid p‘).html(book.bid); ???????????$(‘#title p‘).html(book.title); ???????????$(‘#price p‘).html(‘¥‘+book.price); ???????????var d = new Date(book.pubDate); ???????????$(‘#pubDate p‘).html(d); ???????????$(‘#intro p‘).html(book.intro); ???????} ???});</script></body></html>//其余两个html内容省略<!DOCTYPE html><html><head lang="en"> ???<meta charset="UTF-8"> ???<title></title></head><body> ???<h1>更新书籍内容</h1> ???<hr/> ???<script src="js/jquery-1.11.3.js"></script></body></html><!DOCTYPE html><html><head lang="en"> ???<meta charset="UTF-8"> ???<title></title></head><body> ???<h1>添加书籍</h1> ???<hr/> ???<script src="js/jquery-1.11.3.js"></script></body></html>
//执行程序app.jsconst http = require(‘http‘);const express = require(‘express‘);const book = require(‘./book‘);var app = express();http.createServer(app).listen(8080);//使用中间件向客户端返回静态内容app.use(express.static(‘public‘));//定义路由,向客户端返回动态内容app.get(‘/book‘, book.getAll);//自建一个book模块,调用getAll方法
//自建模块book.jsconst mysql = require(‘mysql‘);//数据库连接池var pool = mysql.createPool({ ???user:‘root‘, ???database:‘dangdang‘, ???connectionLimit:5});module.exports = { ???getAll:(req, res)=>{ ??????pool.getConnection((err,conn)=>{ ??????????conn.query(‘SELECT * FROM book‘,(err,result)=>{ ??????????????//把查询结果集转换为JSON字符串,输出给客户端 ??????????????res.json(result); ??????????????conn.release();//释放连接回连接池 ??????????}) ??????}) ???}};
效果:
【重点突破】——使用Express创建一个web服务器
原文地址:http://www.cnblogs.com/ljq66/p/7630290.html