Node.js從入門到放棄(四)

Node.js從入門到放棄(四)

前言

這是該系列文章的第四篇,主要介紹如何使用express+模板引擎做一個完整的案例

模板引擎

模板引擎是爲了使用戶界面與業務數據(內容)分離而產生的,最初源自服務端,後來發展到前端。如果你學過java,應該知道jsp,用過springboot 應該知道thyemleaf,這都屬於模板引擎。當然,這東西現在不是很火了,對前端而言,react,angular,vue的出現,是根本上的變革,react以js爲模板,vue和angular以html爲模板。目前主流的模板引擎有underscore,art-template,jade,ejs… 使用方法大同小異,這裏只介紹art-template

art-template

這裏舉個例子,簡單介紹下art-template在node中的應用

  • 項目初始化:新建一個項目,進入後輸入npm init -y
  • 安裝: npm i art-template
  • 根目錄寫下新建index.html(名稱可自定義),寫入如下內容
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>

     <p>姓名->{{ name }}</p>
     <p>年齡 ->{{ age }} 歲</p>
     <p>涉獵語言->{{each language}} {{ $value }} {{/each}}</p>

</body>
</html>

  • 根目錄寫下新建app.js(名稱可自定義),寫入如下內容
var template = require('art-template')//加載模板引擎
var fs = require('fs')//加載fs文件操作模塊
//讀取html文件
fs.readFile('index.html', function (err, data) {//引入模板文件
  if (err) {
    return console.log('讀取文件失敗');
  }
  //模板引擎不支持二進制,需要轉成字符串
  var result = template.render(data.toString(), {//用render方法填充數據
    name: '冷月心',
    age: 18,
    language: [
      'JAVA',
      'PHP',
      'Node.js'
    ]
  })

  console.log(result)
})

  • 運行node app.js
  • 效果圖

在這裏插入圖片描述

  • 可以看到,我們填充的數據都被渲染出來了,這就是模板引擎

綜合案例

下面寫一個綜合小案例,先簡單羅列下涉及的點,做到心中有數

  • 工程規範
  • 模板引擎和express整合,數據渲染
  • 中間件處理post請求
  • 404攔截處理
  • 忽略favicon.ico請求
  • 路由配置
  • 靜態資源開放
  • 文件上傳
  • 文件下載
  • 路由重定向
  • 其他…

step 1–工程目錄

在這裏插入圖片描述

step2–依賴安裝

npm i express
npm i art-template  express-art-template 
npm i formidable //處理post請求和文件上傳

step3–整合配置

這裏主要乾了五件事,整合模板引擎,導入並掛載路由,404攔截,忽略favicon.ico請求,開放靜態資源

app.js

//1. 引包
const express = require('express')
//2. 獲取服務器對象
const app = express()
//3. 引入路由
const router = require("./routes")
//4. 整合模板引擎
app.engine('html', require('express-art-template'))

//5. 開放靜態資源
app.use(express.static("public"))

//6. 掛載路由
app.use(router)

//7. 404攔截 寫在最後一個路由後邊


app.use( (req, res)=> {
  if(req.url==="/favicon.ico") {
    res.send(null)
  } else{
    res.render("404.html")
  }
})

//設置監聽
app.listen(3000, () => {
  console.log('run server___')
})



routes/index.js

這裏是路由配置的細節

//引入express formidable
const express = require("express");
const formidable = require('formidable');
//創建路由實例
const router = express.Router()

//路由配置--渲染首頁
router.get('/', (req, res) => {
    //注意,這個index.html直接對應views文件夾下的index.html
    res.render('index.html', {
        title: "hello world"
    });
})

//路由配置--渲染form表單
router.get('/form', (req, res) => {
    res.render('form.html');
})

//路由配置--渲染form表單
router.get('/backHome', (req, res) => {
    //重定向到首頁
    res.redirect("/")
})



//路由配置--處理form表單的post請求,並將處理後數據渲染到show.html
router.post('/post', (req, res) => {
    const form = new formidable.IncomingForm();

    form.parse(req, (err, fields, files) => {

        res.render('show.html', {
            fields
        });
    })
})



//導出路由
module.exports = router

此時的項目目錄

在這裏插入圖片描述

  • index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>index</title>
</head>

<body>

    <h2>{{title}}</h2>

    <!-- 注意,這時候的鏈接是後端路由 -->
    <a href="/form">點擊去填寫form表單</a>
</body>

</html>


  • 404.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>404</title>
</head>

<body>

    404 not found
</body>

</html>


  • show.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>show</title>
</head>

<body>

    <h2>數據渲染</h2>
    <div>
        <p>name--{{fields.name}}</p>
        <p>age--{{fields.age}}</p>
        <!-- 其實可以直接href="/",這裏是爲了演示重定向 -->
        <a href="/backHome">返回首頁</a>
    </div>
</body>

</html>
  • form.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>form</title>
</head>

<body>
    <h2>填寫表單</h2>
    <!-- 這裏/post也對應後端路由 -->
    <form action="/post" method="POST">
        <p> <input type="text" name="name" value="冷月心"></p>
        <p> <input type="text" name="age" value="18"></p>
        <input type="submit" value="提交">
    </form>
</body>
</html>

step4–測試邏輯

  • 訪問根目錄,跳轉到首頁/

在這裏插入圖片描述

  • 點擊鏈接,跳轉到/form

在這裏插入圖片描述

  • 點擊提交,表單數據在/show顯示

在這裏插入圖片描述

  • 點擊返回首頁,跳轉到首頁/

  • 靜態資源開放,訪問/avatar.jpg,顯示圖片
    在這裏插入圖片描述

step5–上傳下載

到這裏功能點就實現了一大半,剩下的是上傳和下載,先介紹上傳

  • views下新建upload.html,寫入如下內容

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>upload</title>
</head>

<body>
    <h2>文件上傳</h2>
    <form action="/upload" method="POST" enctype="multipart/form-data">
        <p> <input type="file" name="pic"></p>
        <input type="submit" value="上傳">
    </form>
</body>

</html>
  • 後臺接口處理

//路由配置--渲染上傳表單
router.get('/upload', (req, res) => {

    res.render("upload.html")
})

// 路由配置--處理文件上傳
router.post('/upload', (req, res) => {
    const fs = require('fs');
    const path = require('path');

    const form = new formidable.IncomingForm();
    //設置文件上傳存放地址
    form.uploadDir = "./public";
    //保持拓展名
    form.keepExtensions = true;
    //執行裏面的回調函數的時候,表單已經全部接收完畢。
    form.parse(req, (err, fields, files) => {

        //可以在這裏改個名
        const oldpath = path.resolve(__dirname, "../public/" + path.basename(files.pic.path));
        const newpath = path.resolve(__dirname, "../public/" + files.pic.name)

        fs.renameSync(oldpath, newpath)

        if (err) {
            res.send("上傳失敗", err.message)
            return
        } else {
            res.send("上傳成功")
        }



    });
})



  • 訪問/upload,,選擇一張圖片

在這裏插入圖片描述

  • 上傳效果圖

在這裏插入圖片描述


在這裏插入圖片描述

文件下載

到這裏就是最後一個功能點了,下載的邏輯其實很好實現,views下新建download.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>download</title>
</head>

<body>

    <a href="/downAvatar">點我下載avatar.jpg</a>


</body>

</html>

  • 後臺編寫 downAvatar接口

//路由配置--下載頭像
router.get('/downAvatar', (req, res) => {
    const path = require("path")
    res.download(path.resolve(__dirname, "../public/avatar.jpg"), (err) => {
        if (err) {
            res.send("下載失敗")
        }
    })
})

  • 測試,訪問/download

在這裏插入圖片描述

  • 點擊

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章