前端學習 node 快速入門 系列 —— 服務端渲染

彭加李發表於2021-03-15

其他章節請看:

前端學習 node 快速入門 系列

服務端渲染

簡易版 Apache一文中,我們用 node 做了一個簡單的伺服器,能提供靜態資源訪問的能力。

對於真正的網站,頁面中的資料應該來自伺服器(伺服器查詢資料庫),我們來模擬一下。請看示例:

- demo
    - node_modules                  // 安裝 art-template 後自動生成
    - public            
        - lib  
            - art-template          // 將 node_modules/art-template 拷貝過來即可
        - view         
            - client-render.html    // 頁面內容採用客戶端渲染
            - server-render.html    // 頁面內容採用服務端渲染
    - index.js                      // 入口檔案
    - package.json                  // 只依賴於 art-template 

:如果不明白 node_modules、package.json,可以看我的另外一篇文章(npm

client-render.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src='/public/lib/art-template/lib/template-web.js'></script>
</head>
<body>
   <h2>客戶端渲染</h2>
   <div id="content"></div>
    <script id="test" type="text/html">
        <p>{{title}}</p>
        <ul>
        {{each list as value i}}
            <li>索引 {{i + 1}} :{{value}}</li>
        {{/each}}
        </ul>
    </script>
    <script>
        var data = {
            title: '標籤',
            list: ['文藝', '部落格', '攝影']
        };
        // 前端使用模板引擎
        var html = template('test', data);
        document.getElementById('content').innerHTML = html;
    </script>
</body>
</html>

server-render.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>服務端渲染</h2>
   
    <p>{{title}}</p>
    <ul>
    {{each list as value i}}
        <li>索引 {{i + 1}} :{{value}}</li>
    {{/each}}
    </ul>
</body>
</html>

index.js:

const http = require('http')
const fs = require('fs')
const template = require('art-template')
const server = http.createServer()

const requestListener = (req, res) => {
    let url = req.url
    // 客戶端渲染
    if(url.endsWith('client-render.html')){
        fs.readFile('./public/view/' + url, (err, data) => {
            if (err) throw err;
            res.end(data)
        });
        return
    }
    // 服務端渲染
    if(url.endsWith('server-render.html')){
        fs.readFile('./public/view/' + url, (err, data) => {
            if (err) throw err;
            // 服務端使用模板引擎
            const ret = template.render(data.toString(), {
                title: '標籤',
                list: ['文藝', '部落格', '攝影']
            });
            res.end(ret)
        });
        return
    }
    fs.readFile('.' + url, (err, data) => {
        if (err) {
            res.writeHead(404, {'Content-type':'text/html;charset=utf8'})
            res.end('沒有找到對應的資源')
        }
        res.end(data)
    })
}

server.on('request', requestListener)
server.listen('3000', () => {
    console.log('伺服器已啟動')
})

啟動伺服器:

$ node index

訪問:

1. 瀏覽器輸入 http://localhost:3000/server-render.html

頁面顯示:<是有樣式的>
服務端渲染
標籤

索引 1 :文藝
索引 2 :部落格
索引 3 :攝影

2. 瀏覽器輸入 http://localhost:3000/client-render.html
頁面顯示:<與 server-render.html 相同>

雖然兩個頁面看起來相同,但一個是客戶端渲染,一個是服務端渲染

Tip:模板引擎是為了使使用者介面和業務資料分離而產生的,它可以生成特定格式的文件。模板引擎最初出現在服務端。

這裡使用的模板引擎是 art-template。模板引擎應用在客戶端就是客戶端渲染;模板引擎應用在服務端就是服務端渲染。更直觀的區分,如果原始碼(瀏覽器快捷鍵:ctrl+u)中可以找到前端頁面的文字,則說明是服務端渲染,否則是客戶端渲染。

:網站通常既有客戶端渲染,也有服務端渲染。例如噹噹網、京東這類電商網站,商品通常使用服務端渲染,因為商品需要被搜尋引擎看見;而評論、試讀則會使用客戶端渲染。

其他章節請看:

前端學習 node 快速入門 系列

相關文章