个人博客的三种渲染方式

个人博客第一种实现方法

实现思路

个人博客实现思路:
首页index.html上有很多目录,点击目录会跳转到某一篇文章页面page.html下,这些文章页面有相同的框架,只是标题内容不同。

下面介绍第一种最简单的实现方法:

创建很多个html文件,每一篇不同的文件对应不同的文章,在index.html(首页文件)当中以列表的形式引入每一篇文章文件,通过a标签把首页和文章链接起来。点击目录,会跳转到某一篇文章页面。

具体实现

1、首先下载可能需要的插件
body-parser、express、mongodb
2、创建服务器文件index.js
引入express

const express=require('express')

创建服务器app

const app=express()

利用express的static引入静态目录
注意静态目录默认文件是index.html,如果更改文件名比如demo.html,需要设置static方法的第二个参数为index:false

app.use(express.static('./static',{index:false}))
//表示不把默认的index.html作为主页文件
//帮助管理静态文件

监听3000端口

app.listen(3000)

3、服务器创建完毕,接下来创建我们需要的static文件夹,保存需要的静态文件
3.1、首先设置静态目录下的文章文件和首页文件,对他们简单设置一些样式即可
page1.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./../css/page.css">
</head>
<body>
    <nav>佩奇的专栏-----佩奇跟你唠唠嗑</nav>
    <h3>母猪的产前护理</h3>
    <p>母猪在产前就需要精心照顾</p>
</body>
</html>

page2.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./../css/page.css">
</head>
<body>
    <nav>佩奇的专栏-----佩奇跟你唠唠嗑</nav>
    <h3>母猪的产后护理</h3>
    <p>母猪在产后需要补充营养</p>
</body>
</html>

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/page.css">
</head>
<body>
    <nav>佩奇的专栏-----佩奇跟你唠唠嗑</nav>
    <div class="wrap">
        <ul>
            <li>
                <a href="./pages/page1.html">母猪的产前护理</a>
            </li>
            <li>
                <a href="./pages/page2.html">母猪的产后护理</a>
            </li>
        </ul>
    </div>
</body>
</html>

对他们设置css样式:

*{
    margin: 0;
    padding: 0;
}
nav{
    width: 100%;
    height: 70px;
    background-color: deeppink;
    color: white;
    font-weight: bold;
    line-height: 70px;
    font-size: 30px;
    padding-left: 50px;
}
h3{
    padding-left: 50px;
    padding-top: 20px;
}
p{
    padding-left: 50px;
}
.wrap{
    padding-left: 50px;
    padding-top: 20px;
}

优缺点

优点:
实现简单:给每个文章复制粘贴相同的html文件,手动修改标题和内容,把静态html链接到首页a标签,实现静态文件跳转。
缺点:
1、如果想要更改页面的版式,那么所有的文件都要更改,维护极其困难;
2、文章并不能动态更新,因为每篇文章都是在html文件里写死的;
3、文章的查找功能、搜索功能根本没办法实现。

个人博客第二种实现方法

实现思路

下面介绍个人博客的第二种实现方法:

Ajax无法实现跨页,所以只在一个页面内就能完成请求。

在首页内设计上下两个版块,上面显示所有文章列表,下面点击时能出现对应文章的标题和内容。

把所有的信息(title和content)都存储在Mongodb中,首页向服务器发起Ajax请求,请求所有文章列表,服务器查找数据库中所有的数据返回给前端,前端把它渲染到页面。

点击某一个标题,携带该标题的id向服务器发起请求,服务器查找对应id的数据返回给前端,前端把内容渲染到页面。

具体实现

1、设计首页页面,分成上下两部分

<div>
        <ul class="list">
            <li>母猪的产后护理</li>
        </ul>
</div>
<hr>
<div class="content"></div>

2、在前端设计getList方法,发起Ajax请求,向服务器请求所有的文章列表
请求方式为GET请求,向后台list接口请求数据,因为要获取所有的数据所以不需要传递data,当成功获取到信息,执行填充页面函数。

var getList=function(){
            $.ajax({
                type:'GET',
                url:'/list',
                data:{},
                success:function(jieguo){
                    // console.log(jieguo)
                    fillList(jieguo)
                }
            })
        }

3、设计填充页面的函数
传递过来的结果中包含所有信息,这些信息是以数组形式传递的,数组中的每一个条对象都是一条数据。
定义一个空字符串,遍历数组每一项,以模板形式把每一项的title属性放到li标签里,再把所有的li标签加到html字符串中,这样html字符串就有了所有包裹着文章标题的li标签,再把li标签渲染到列表中即可。
注意:每个li要有一个id属性,以便设计后点击事件时使用。

var fillList=function(arr){
            // 填充页面的方法
            var html=''
            arr.forEach(function(item,index){
                html+=`<li class="item" data=${item._id}>${item.title}</li>`
            })
            $('.list').html(html)
            // 拼接好的字符串渲染到页面上
        }

4、设计服务器文件index.js
引入需要的express、mongoControl文件
初始化服务器文件

const express=require('express')
//引入mongoControl   数据库操纵文件
const mongoControl = require('./mongoControl')
// 初始化一个用于博客的库和表
const blogControl = new mongoControl('text', 'page')
const app=express()
app.listen(3000)

引入静态目录

app.use(express.static('./static'))

设计请求数据列表的接口
在blogControl数据库里查找所有的数据发送给前端

// 请求数据列表的接口
app.get('/list',function(req,res){
    blogControl.find({},function(jieguo){
        res.send(jieguo)
    })
})

至此,localhost:3000能显示所有的文章标题
在这里插入图片描述
接下来设计点击事件,点击某一篇文章,下面的内容区显示相应的内容。
5、设计获取文章内容的函数
向后台getContent接口发起请求,携带一个id值,后台寻找id值对应的内容,获取成功,把结果中的文章内容取出来,显示到内容区。

var getContent=function(_id){
            $.ajax({
                type:'GET',
                url:'/getContent',
                data:{
                    _id:_id
                },
                success:function(jieguo){
                    $('.content').html(jieguo[0].content)
                }
            })
        }

6、设计点击事件
在填充页面时,把每个被渲染上去的标题都挂上监听器,点击执行getContent函数,传入当前id。

$('.item').on('click',function(){
      getContent($(this).attr('data'))
      // $(this).attr(data)获取当前点击触发了回调函数的data属性值
})

7、在后台设计请求文章内容的接口
先取出得到的id,根据id在数据库中查找数据,查找成功,把查找到的数据返回给前端。

// 根据点击时的id获取内容
app.get('/getContent',function(req,res){
    // console.log(req.query._id)
    var _id=req.query._id
    blogControl.findOneById(_id,function(jieguo){
        res.send(jieguo)
    })
})

实现效果

在这里插入图片描述

优缺点

优点:
1、使用了模板形式的开发,要想修改版式,只要修改模板就好了,维护简单;
2、所有数据都是存储在mongodb中的,可以进行搜索,排序,查找等,内容可管理;
3、Ajax的浏览体验不错;
4、大部分的html替换、渲染都是在用户的浏览器进行的,所以服务器的压力就会变小。

缺点:
1、整个项目都是在一个页面内进行,浏览列表和文章内容没有分离,无法实现大型网站系统,只适合做小的单个应用;
2、SEO优化无法完成,搜索引擎的爬虫不会去执行我们的js代码,对它来说,我们的项目只是一个空壳,没有爬取的必要。

前两种方法存储的都是html格式的数据,存储非常困难,接下来我们将解决这个问题。

个人博客第三种实现方法

后端渲染实现思路

前端渲染:前端像后端发起请求,后端设计相应的接口接受请求,查询数据库,给前端发送json格式的结果,前端把json结果通过replace拼接到页面上;
后端渲染:前端只是作为一个模板存在,后端通过fs模块读取index.html文件,获得完整的html文件的字符串,后端自己向数据库请求需要的数据,后端再把查询到的数据通过replace替换html模板里的内容,得到最终完整的html字符串,再把整个字符串一起发送给前端。

前两种方法其实都是前端的渲染,在这里,我们采用后端渲染的方式来实现博客。

后端渲染具体实现

1、设计主页模板

主页中有一个列表来接受文章题目就行。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="wrap">
        <ul>
            <!--allList-->
        </ul>
    </div>
</body>
</html>

2、设计文章页面模板

文章页面设计两个待替换的符号,用来放文章标题和内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>佩奇的专栏-----佩奇跟你唠唠嗑</h1>
    <div class="wrap">
        <h3><!--title--></h3>
        <p><!--content--></p>
    </div>
</body>
</html>

3、设计服务器文件

3.1初始化服务器文件,引入需要的模块
在这里,我们不使用static来处理静态目录下的文件,我们需要的是可以动态发生变化的文件,不是某一个写死的文件,我们自己处理/接口请求。

const express=require('express')
const fs=require('fs')
//引入mongoControl
const mongoControl = require('./mongoControl')
// 初始化一个用于博客的库和表
const blogControl = new mongoControl('text', 'page')
const app=express()
app.listen(3000)

3.2处理首页目录(也就是/接口)接口请求

通过fs模块的readFile方法读取index.html文件,获得一个html的字符串,得到的字符串作为我们的tpl模板。
因为我们要拼接的是文章题目列表,有很多条数据,我们先定义一个中间字符串html来接收一下所有的li标签。
在blogControl数据库中查询所有信息,得到一个数组,遍历这个数组,使用es6语法拼接li标签,赋值给html,遍历完成之后,html就是待拼接的li组。
(注意:拼接li标签的时候,记得给每个标签设计一个独特的id,方便之后点击跳转页面使用)
再把tpl中待替换的部分replace成html。
最后,把替换好的tpl发送给前端。

app.get('/',function(req,res){
    fs.readFile('./static/index.html',{encoding:'utf-8'},function(err,result){
        if(err){
            res.status(500)
            return
        }
        // console.log(result)
        // 此时的result就是获取到的index.html模板
        var tpl=result
        // 去数据库中查找信息
        var html=''
        blogControl.find({},function(jieguo){
            // console.log(jieguo)
            // jieguo就是包含所有信息的数组
            jieguo.forEach(function(item,index){
                html+=`<li><a href="/p?_id=${item._id}">${item.title}</a></li>`
            })
            tpl=tpl.replace('<!--allList-->',html)
            res.send(tpl)
        })
    })
})

3.3处理文章页面/p接口请求

首先获取地址栏传递的参数_id,读取page.html文件,得到文章页面的模板。
去blogControl数据库根据id查询数据,把结果中的title和content通过replace方法替换到模板相应位置,替换结果赋值给html就行。
(注意:这里不需要中间字符串,一篇文章只替换一次标题和一次内容就行,不需要替换很多次)
后端把html字符串发送给前端

app.get('/p',function(req,res){
    var _id=req.query._id
    fs.readFile('./static/page.html',{encoding:'utf-8'},function(err,result){
        blogControl.findOneById(_id,function(jieguo){
            // jieguo中包含查询到的信息
            var html=''
            var json=jieguo[0]
            html=result.replace('<!--title-->',json.title)
                    .replace('<!--content-->',json.content)
            // console.log(html)
            res.send(html)
            // !!!!!!注意,不要写错代码位置
            // 发送文件要在替换完之后,注意不要写在代码块外,否则还没有查询数据就发送数据,页面当然为空啊
        })
        
    })
})

后端渲染优缺点

优点:
1、因为我们请求获得的是完整的html内容,所以搜索引擎优化很好;
2、适合制作多个页面的整体逻辑。

缺点:
因为服务器文件的逻辑相比前两个过于复杂,填充过程也比较复杂,所以对后端的压力很大。

ejs优化

上面使用模板的方式过于复杂,可以通过ejs模板引擎来进行优化。

1、在后端index.js文件引入ejs

const ejs=require('ejs')

2、使用ejs处理主页接口请求接口
上面手写模板是先读取文件,再查找数据去渲染;
使用ejs先查找对应的数据,把数据通过ejs的renderFile方法发送给index.ejs,在index.ejs文件里进行数据的渲染。
注意ejs的语法使用:把每一行的js语句用<% %>包裹起来,把变量的调用用<%= %>包裹起来。

blogControl.find({},function(jieguo){
        ejs.renderFile('./static/index.ejs',{data:jieguo},function(err,result){
            res.send(result)
        })
    })
<!-- data传到这里来,data是一个数组,遍历数组 -->
            <% data.forEach(function(item,index){ %>
                <li><a href="/p?_id=<%= item._id %>"> <%= item.title %> </a></li>
            <% }) %>

3、处理文章接口请求

原理同上

blogControl.findOneById(_id,function(jieguo){
        var data=jieguo[0]
        // console.log(data)
        ejs.renderFile('./static/page.ejs',{data:data},function(err,result){
            // console.log(result)
            res.send(result)
        })
    })
<h3><!--title-->
     <%= data.title %>
</h3>
<p><!--content-->
     <%= data.content %>
</p>

大大简化代码。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值