实战练习

Node.js 实战练习(下)

怎么使用 express 搭建一个查询网站,怎么将数据导出为 excel 格式

2018-10-14侠课岛    基础入门       

后端/Node.js/Node.js入门 35     0     3674

在这章的上半部分,我们制作了一个爬虫工具来抓取数据,并将抓取到的数据储存到 MySQL 中。这一部分,我们将把这些数据已网站的形式进行展示出来,并导出成我们想要的格式。为什么要再做成网站的形式呢?一方面是 Node 本身就可以作为网站的服务端来使用;另一方面随着越来越多的前端工具都利用到 Node 如 webpack、glup、vue-cli 等,因此想要告诉大家,现在的 Node 是可以完整打造前后端的。

5.3 查询:使用 express 搭建一个查询网站

如今在前后端分离开发的趋势下,搭建一个网站可以是前端和后端同步进行的。不过我们现在只有一个人,那么还是从服务端开始做起吧。首先我们创建好 server 目录,用来存放服务端的代码,在 server 目录中新建 app.js 作为服务器的主入口、config.js 作为服务端配置文件、contraoller.js 作为控制中间件、dao.js 作为数据库操作文件。建完后目录结构如下图。

为什么要如此繁琐呢?接触过后端的同学相信比较熟悉这套模式,这样正是后端 MVC 模式的体现。每一个模块各司其职,虽然文件和代码上看起来多了,但实际在生产过程中因为分类清晰范围明确,反而易于我们修改和调整。本项目中 app.js 作为总入口,负责调用 controllercontroller 负责处理各种业务逻辑,而 dao 则负责与数据库进行交互。因为逻辑简单本项目中这些以文件的形式来划分,在实际过程中,往往会以目录的形式进行划分。

1. 服务端搭建

在第四章中,我们有介绍 Node 的 http 模块可以轻松搭建起一个服务器。但是,原生的 http 模块只提供了一些基础的接口,在实际使用中需要我们自己进行封装、修改。因此在实际项目中我们会使用第三方的模块进行搭建。本项目中用到的就是 express 框架。

express 是一个简单好用的框架,对 Node 的 http 模块进行了封装,让我们可以很轻松地对请求进行处理。使用 express 构建服务器比 http 更为轻松。下面我们就先来用express 搭建我们的服务器。

var chalk = require('chalk')
var express = require('express')

var PORT = 3000
var app = express()

app.get('/', (req, res)=>{
  res.send('Hello from express !')
  res.end()
})

app.listen(PORT, ()=>{
  console.info(chalk.yellow(`服务器已经启动,正在监听端口 ${PORT}`))
})

仅仅十多行的代码就构建出了一个简单的服务器。我们可以试着运行一下服务器。

在浏览器中可以看到我们的效果。

目前我们是针对 / 做了解析,任意的请求都会返回 Hello from express。但是实际上,网站会根据 url 的不同返回不同的内容,这就是路由的作用。在 express 中,已经帮我们做好了路由的功能,我们只要设定好 app 对应的方法和路径就可以了。这里我们设定 /getMovies 作为我们获取电影信息的路径。

app.get('/getMovies/:start/:rows', (req, res) => {
  var start = req.params.start
  var rows = req.params.rows
  movieController.getMovie(start, rows).then((result) => {
    console.log(result)
    res.send(result)
    res.end()
  })
})

先等等,别急着运行。我们这个请求的实际处理还没做,这里请求的实际处理我们写在 controller.js 中,具体逻辑先不细写。就先返回一个字符串消息做测试。

async function getMovie(start, rows) {
  return `传入的 start = ${start}, rows = ${rows}`
}

module.exports = {
  getMovie
}

好了,这下我们逻辑就串起来了。现在,再让我们运行一下。服务器启动后再在浏览器中输入 url 验证一下。

嗯,结果顺利显示。那么我们就把 controller.js 的逻辑补起来。controller 主要是根据请求从数据库抽取数据,然后进行一定的处理再返回给前台。而数据抽取的逻辑我们是放在 dao.js 中。那么,我们来看一下 dao.js 的逻辑。 dao.js 数据抽出逻辑。

async function getMovieLimited(start, rows) {
  try {
    var dataList = await knex.select().from('movie').limit(rows).offset(start).orderBy('id', 'asc')
    return dataList
  } catch (err) {
    throw new Error(err)
  }
}

我们通过 limitoffset 控制每次查询的范围和条数。为了保证通用,这两个数字都是通过传入的参数进行控制的。我们在 dao.js 中写好逻辑,然后在 controller.js 中进行调用,随后把结果返回给 app.jsapp.js 返回给客户端。 controller.js调用逻辑。

async function getMovie(start, rows) {
  var movieList = await dao.getMovieLimited(parseInt(start), parseInt(rows))
  return movieList
}

app.js 请求处理逻辑。

app.get('/getMovies/:start/:rows', (req, res) => {
  var start = req.params.start
  var rows = req.params.rows
  movieController.getMovie(start, rows).then((movieList) => {
    res.send(movieList)
    res.end
  })
})

逻辑编写完成后,我们启动服务器,并在浏览器中输入 http://localhost:3000/getMovies/25/25 来查询从第 26 条开始,到第 50 条的结果。

请求顺利获取到数据,证明我们的逻辑和代码是正确的。在进入下一步页面设计之前,让我们再次回顾一下我们程序中的整个请求的流程。

2. 页面搭建

在上一节中,我们看到浏览器成功接收了服务端返回的数据。但是,数据的展示方式对我们人类很不友好。这个时候,就需要用页面进行展示了。这里我们就使用 vue 来进行页面的开发。

我们在 server 目录下新建 view 目录用来存放页面,在 view 目录下新建 index.html 作为我们的页面文件。目录的结构如下图所示。

那么接下来我们就在 index.html 加入具体的逻辑。由于页面简单,我们直接通过引入 CDN 资源的方法,以传统的方式开发页面。

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Movie Catalog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" type="text/css" href="http://unpkg.com/iview/dist/styles/iview.css">
  <link rel="stylesheet" type="text/css" href="./index.css">
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script type="text/javascript" src="http://vuejs.org/js/vue.min.js"></script>
  <script type="text/javascript" src="http://unpkg.com/iview/dist/iview.min.js"></script>
</head>

<body>
  <div id="app" class="content"></div>
  <script type="text/javascript" src="./index.js"></script>
</body>

</html>

其中,index.jsindex.css 分别是我们页面的逻辑与样式。剩下的我们引入 axios 作为 http 请求用的库;vueiview 作为框架和 UI库。由于 js 跨域的问题,当我们在进行页面开发时,我们会先用模拟数据 mock 数据进行开发。在这里,我们也先用假的数据进行开发,来确定样式。

我们简单地用 html 搭建好基本的框架,body 中的部分。CSS 的部分这里就不放出了。

<body>
  <div id="app" class="content">
    <div class="header">
      <h1 class="hd-title">豆瓣电影Top 250 目录</h1>
    </div>
    <hr />
    <div class="body">
      <ul class="bd-movie-list">
        <li class="movie-list-item">
          <Row>
            <i-col span="8">
              <img src="" alt="movie-pic" class="movie-pic" />
            </i-col>
            <i-col span="16">
              <div class="movie-body">
                <div class="movie-title">
                  Movie title
                </div>
                <div class="movie-content">
                  Movie content
                </div>
                <div class="movie-quote">
                  Movie quote
                </div>
              </div>
            </i-col>
          </Row>
        </li>
      </ul>
    </div>
  </div>
  <script type="text/javascript" src="./index.js"></script>

</body>

浏览器中运行的结果如下。接下来,我们将把服务器与页面联系起来并且将数据填写到页面中去。

本教程图文或视频等内容版权归侠课岛所有,任何机构、媒体、网站或个人未经本网协议授权不得转载、转贴或以其他方式复制发布或发表。

评价

35

本课评分:
  •     非常好
难易程度:
  •     适中的
|
教程
粉丝
主页

签到有礼

已签到2天,连续签到7天即可领取7天全站VIP

  • 1
    +2 金币
  • 2
    +3 金币
  • 3
    +5 金币
  • 6
    +7 金币
  • 5
    +6 金币
  • 4
    暖心福利
    自选分类VIP ×1天
  • 7
    惊喜大礼

    自选分类VIP ×3天 +20金币
  • 持续签到 +8 金币

金币可以用来做什么?