zoukankan      html  css  js  c++  java
  • 【重点突破】——使用Express创建一个web服务器

    一、引言

    在自学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中进行下载,安装这两个模块,具体过程如下:

    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。

    四、引例说明

    使用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.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();
                })
            })
        }
    };

    效果:

     


     注:转载请注明出处

  • 相关阅读:
    数据类型及用法
    NFS与SSH
    nginx服务,nginx反向代理
    rpm软件包管理
    磁盘分区,文件系统,软链接和硬链接,内存和进程管理
    Linux常用命令,文件目录和权限管理
    操作系统与网络协议(day3)
    计算机基础之硬件简介(Day2)
    QT写串口
    485传输
  • 原文地址:https://www.cnblogs.com/ljq66/p/7630290.html
Copyright © 2011-2022 走看看