【重点突破】——使用Express建立一个web服务器

1、引言css

在自学node.js的过程当中有一个很是重要的框架,那就是Express。它是一个基于NodeJs http模块而编写的高层模块,弥补http模块的繁琐和不方便,可以快速开发http服务器。这里,就要用Express建立一个Web服务器,用来深刻的理解这个框架,并熟悉建立Web服务器的过程。html

 

2、核心概念——中间件node

 

Express 是一个自身功能极简,彻底是由路由和中间件构成一个的 web 开发框架:从本质上来讲,一个 Express 应用就是在调用各类中间件。mysql

 

中间件(Middleware) 是一个函数,它能够访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处于请求-响应循环流程中的中间件,通常被命名为 next 的变量。jquery

 

中间件的功能包括:web

  • 执行任何代码。
  • 修改请求和响应对象。

终结请求-响应循环。调用堆栈中的下一个中间件。ajax

若是当前中间件没有终结请求-响应循环,则必须调用 next() 方法将控制权交给下一个中间件,不然请求就会挂起。sql

  

Express 应用可以使用以下几种中间件:数据库

  • 应用级中间件
  • 路由级中间件
  • 错误处理中间件
  • 内置中间件
  • 第三方中间件

使用可选则挂载路径,可在应用级别或路由级别装载中间件。另外,你还能够同时装在一系列中间件函数,从而在一个挂载点上建立一个子中间件栈。express

 

 

app.use(url,  (req, res, next)=>{ //.....中间件要执行的代码 next( ); //调用下一个中间件或路由

 

3、模块下载

由于建立Web服务器要用到第三方模块的mysql和Express,因此须要在建立新项目以后,在NPM中进行下载,安装这两个模块,具体过程以下:

  1. Webstorm建立新项目project,右键点击project
  2. show in Explorer 进入目标文件夹 
  3. 按shift  同时点击右键,在空白面板处
  4. 在此处打开命令窗口
  5. >npm  i  mysql    等待下载
  6. >npm  i  express  等待下载

下载完成后,webstorm中新建立的project下会自动更新出一个node_modules目录,里面会有须要的mysql和Express。

 

4、引例说明

使用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目录下的某个资源,它能够直接向客户端返回,不会再调用后续的路由。

 

 

5、web服务器建立

要求:使用Express建立Web服务器应用,能够接收以下的请求:

一、编写SQL:建立数据库dangdang,书籍信息表book(bid,title,price,pubDate-出版日期,into-内容简介),并插入4行书籍记录。

 

二、至少能够向客户端提供以下静态资源:

/public/booklist.html      初始时显示一个空白的表格,页面加载完成后向服务器异步请求全部的书籍信息。

/public/jquery-1.11.3.js     在DIV中显示某一本书的详情

/public/book_detail.html  在DIV中显示某一本书的详情

/public/book_add.html   显示一个添加书籍的表单,点击“提交”按钮,异步提交给服务器

/public/book_update.html  显示一个修改书籍的表单,输入域中是当前要修改的书籍信息,点击“提交”按钮,异步提交给服务器。

 

三、以及以下动态资源地址——注意:下述地址都使用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.js
const 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方法
app.get('/book/:bid', book.getById);
//自建book.js
const 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();//释放链接回链接池
 }) }) }, getById: (req, res)=>{ var bid = req.params.bid; console.log('客户端想查询的书籍编号:'+bid); //根据书籍编号,执行SQL语句,查询出对应书籍的信息,以JSON格式发送给客户端:{"bid":.., "title":...}
        pool.getConnection((err, conn)=>{ conn.query('SELECT * FROM book WHERE bid=?', [bid], (err, result)=>{ //console.log(result); //[ {} ]
                res.json(result[0]); //只须要向客户端返回一个JSON对象便可,无需返回数组
 conn.release(); }) }) } };

 

效果:

 

 


 注:转载请注明出处

相关文章
相关标签/搜索