服务端渲染底层原理-Node学习

本文深入讲解服务端渲染(SSR)的概念、优势及实现过程。SSR不仅提升网页加载速度,更有利于SEO优化,通过模版引擎在服务器端完成数据替换,直接发送解析好的HTML给浏览器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是服务端渲染

我们的网页都是由代码组成的,代码就是字符串,服务期会把浏览器请求的网页,按照字符串格式发送给浏览器,然后浏览器解析这些字符串,我们就能看到网页了。

现在的网页很多都是动态页面,也就是页面的数据会随着用户不同的操作,而进行不同数据的替换,那么这个替换数据的过程,就可以称之为渲染。

这个渲染过程放在浏览器这里进行,就叫做浏览器渲染,常见的有Ajax请求,异步等。

当这个过程放在服务器上完成的时候,就叫做服务端渲染。

举个栗子🌰:

<div>
	{{$value}}
</div>

上面代码中如果是浏览器端渲染,那么服务器会把完整的,带有花括号的字符串发送给浏览器,然后浏览器解析道{{$value}}的时候,会去绑定的数据当中找是什么数据,然后把数据放到<div>标签中,然后解析成下面的样子

<div>
	hello world
</div>

最终再解析上面的html,完成网页渲染。

如果是服务器端渲染,那么浏览器在发送请求之后,服务器会根据请求,找到对应的页面,先把页面转换成字符串,然后利用模版引擎,对
{{$value}}进行替换,替换为hello world之后,再把替换好的字符串,发送给浏览器,这个时候浏览器就会直接解析数据已经被替换好的页面

为什么要使用服务端渲染

服务端渲染利于SEO搜索优化,应为数据都是解析好的,直接交给了浏览器,那爬虫在抓取我们网页信息的时候,就非常好抓,直接摆在明面上。

服务端渲染过程

下方是基于node进行展示的渲染过程

  1. 启动服务器监听端口
  2. 页面发送请求,服务器接收到到之后,根据url,找到对应的相应区域
  3. 读取需要发送给浏览器的页面
  4. 把页面的内容转化成字符串
  5. 利用模版引擎,对字符串中需要替换的数据进行替换(替换的数据可以根据需要,去读取不同的文件)
  6. 将完成替换的字符串发送给浏览器
//node核心模块引入
let http = require('http');
let url = require('url');
let fs = require('fs');

//模版引擎引入
let template = require('art-template');

//页面数据存放数组
let comments = [
    {
        name: 'Tony',
        age: '18',
        sex: 'male',
        date: '2020-04-11'
    },
    {
        name: 'Lucy',
        age: '18',
        sex: 'female',
        date: '2020-04-11'
    },
    {
        name: 'Sun',
        age: '18',
        sex: 'female',
        date: '2020-04-11'
    }
]
/**
 * @param {object} req 浏览器发送过来的请求参数
 * @param {object} res 服务器对相应请求事件参数
 */
http
.createServer(function (req, res) {
    /**
     * 
     * 通过url核心模块的parse方法,可以解析浏览器端请求的地址,适用于get请求解析参数
     * 该方法可直接解析成json格式
     * eg:http://127.0.0.1:3000/submint?name=Tony&age=18&sxe=male
     * Url{
     *  protocol: 'http:',
     *  slashes: true,
     *  auth: null,
     *  host: '127.0.0.1:3000',
     *  port: '3000',
     *  hostname: '127.0.0.1',
     *  hash: null,
     *  search: '?name=Tony&age=18',
     *  query: {name: Tony, age: 18, sex: male},
     *  pathname: '/submint',
     *  path: '/submint?name=Tony&age=18&sxe=male',
     *  href: 'http://127.0.0.1:3000/submint?name=Tony&age=18&sxe=male'
     * }
     */
    let parseObj = url.parse(req.url, true);

    //拿到解析完成后的路径名称
    let pathname = parseObj.pathname;
    if (pathname = '/') {
        //读取文件
        fs.readFile('/view/index.html', function (err, data) {
            if (err) {
                return res.end('404 Not Found.')
            }
            //使用template模版引擎,对刚读取到的 html ‘字符串’进行字符串替换
            let htmlStr = template.render(data.toString(), {
                comments: comments
            })
            res.end(htmlStr);
        })
    } else if (pathname.indexOf('/public/') === 0) {
        fs.readFile('.' + pathname, function (err, data) {
            if (err) {
                return res.end('404 Not Found.');
            }
            res.end(data);
        })
    }else if (pathname === 'submint') {
        //获取上面从地址中解析出来的参数
        let comment = parseObj.query
        comment.dataTime = new Date;
        //将提交的数据放入数组,完成了数据提交
        comments.unshift(comment);

        /**
         * 设置重定向
         * 1.状态码设置成302,临时重定向
         *   statusCod
         * 2.在相应头中通过Location告诉客户端往哪重定向
         *   setHeader
         * 如果客户端收到服务器的相应状态码是302,会自动去Location相应头中找Location
         * 这时便可以看到客户端跳转
         */
        res.statusCode = 302;
        res.setHeader('Location', '/');
        res.end();
    } else {
        fs.readFile('./views/404.html', function (err, data) {
            if (err) {
                return res.end('404 Not Found.')
            }
            res.end(data)
        })
    }
})
/**
 * 监听端口
 * @param {number} 服务器监听的端口号
 * @param {function} 监听成功后执行的函数
 */
.listen(3000, function () {
    console.log('服务器启动成功');
})

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>Document</title>
</head>
<body>
    <div>
    	{{each comments}}
	        <ul>
	            <li>姓名:{{$value.name}}</li>
	            <li>年龄:{{$value.age}}</li>
	            <li>性别:{{$value.sex}}</li>
	            <li>提交日期:{{$value.date}}</li>
	        </ul>
        {{/comments}}
    </div>
</body>
</html>

上面代码是帮助理解服务端渲染过程,并不严谨。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值