一个网站的公共头部head.html和尾部foot.html如何优雅的在整站实现多处复用同步修改?

上个例子,就类似与segmentfault的头部和尾部

网页公共头部:

图片描述

网页公共尾部:

图片描述

这两个地方,是如何在segmentfault整站中实现复用的?

我的思考:

首先,公共的头部和尾部我觉得肯定得复用,如果每个页面再重写一遍,就太low了,我的第一个项目,就是这么做的。至今都让我无法忘却。

其次,后来使用iframe,分别在每个页面里面加载两个iframe,然后把head.html和footer.html放在里面,这是一种解决方案,但是这种方案一旦涉及到修改iframe的宽高,那么就是每个页面都要修改了。

第三,最近的一个项目,用了angularjs,将header和footer直接放在了body里面,变化的部分通过view加载,也实现了我想要的效果,但是url的变化不是很优雅,有点难看。并且这种方式对SEO非常不友好,我不愿意使用。

上面三点是我自己的想法,但是效果都没有让我百分之百的满意,向请教各位同学,你们在项目中是如何处理的?

注意,现在我们不考虑后端任何语言提供的任何模板,只站在前端的角度考虑这个问题

阅读 69.2k
29 个回答

题主,我注意到你的问题中有两个自相矛盾的地方:

上面三点是我自己的想法,但是效果都没有让我百分之百的满意,向请教各位同学,你们在项目中是如何处理的?

注意,现在我们不考虑后端任何语言提供的任何模板,只站在前端的角度考虑这个问题


首先我们要承认一点:现代网站中,基本上都是没有静态页面的。也就是说,只要是个网站,后端都有动态语言在处理请求,在渲染。即便是少数静态博客框架,如jekyll,都是先写好网页模板,再进行预渲染。

因此,对于在项目中是如何处理这个问题:我的回答和前面许多被你反驳的答案一样——用后端模板的include逻辑。

但你后面又加了句注释:现在我们不考虑后端任何语言提供的任何模板,只站在前端的角度考虑这个问题。我觉得这是不合理的。

或许是题主误解了“前后端分离的含义”。也许题主脑海中的前后端分离是指:每次请求都返回一个静态的html文件,再由文件中的脚本对网页的各个部分进行加载。

事实上并不是这样的。

前后端分离是指:后端(Server)负责 Model 层,提供数据,而前端(Browser)负责 Controller 和 View 层,负责将数据渲染。

也就是说:所谓的前后端分离,分离的是数据,前端只是有一个骨架,浏览器加载页面之后,脚本会向服务器拉取数据。一个较常见的例子便是SPA(Single Page Application,单页应用)。

而题主所说的 Header 和 Footer,并不属于数据的范畴。它们只是静态的页面部分。要复用,在后端 include 便好了,前端去拉取?费时,费请求——要知道前端一大忌便是 Too Many Requests。

若题主的理由是可以利用浏览器缓存,减少冗余数据的请求,那我觉得这是本末倒置了。Header 和 Footer,撑死也就几 Kb,为节省这么点带宽去复杂化页面逻辑,还要和数据请求争并发,实在是没有必要。

References: http://blog.jobbole.com/65513/

不服欢迎撕逼。

目前想到三个方案:

  1. 服务器端渲染,几乎所有服务器端语言都有页面模板引擎

  2. 前端组件化开发,将头部和尾部作为组件

  3. 使用gulp等工具来实现拼接,生成目标html文件(不太推荐)

模板引擎不一定要配合后端才能用。
用gulp、webpack等工具都可以很方便的使用node的模板引擎来写html。
大部分模板应该都有继承、引用模块的功能。
写个通用的header、footer是很容易的。
比如用jade:
main.jade

.
.
.
body
  block header
    header
      div.container 顶部
block content
    div#content 内容
  block footer
    footer
      div.container 底部

a.jade

extends main.jade
block content
  div#content a的内容

这样编译出的a.html就有了公用的header、footer,只有内容不一样。

你这种说法肯定是错误的 .

难道一定要 后端才能实现模板吗 ?

Ajax 请求是用来干嘛的 , 难道只能用来加载 数据 .


其实 不光服务器后端语言 .

前端也有很多 , 模板引擎和框架 , 比如 Dot.js 和 Reactjs

在前端 如果不用后端include的 思想
前端框架react 和angularJs都是很好的选择
一个视图
一个路由

看你用什么语言实现了,

php 的话 <? include('header.php'); > <? include('footer.php'); >

angular 是 SPA,直接放 body 就好了

其他语言都有自己的模板系统

目前我厂用的是分出组件,在页面里include进来,发布的时候用gulp来拼

对不起,是我搞错了。

我们的前端用了smarty来做,所以并不是gulp来拼的。不好意思,折叠这条回答吧。


不过,对于这个问题,不建议用js或iframe的方式来做,对SEO不好。

当初我用了一个很low的方法,每一个页面用$.get方法请求头部和尾部,然后插入到页面头部和尾部

用jade试试?

用模板的话 直接引入
PHP的话include

angular自带前端路由和模板,不清楚你说的不够优雅是什么情况。

如果单用angular,就把header和footer封装成directive,views根据routes渲染。

另外还可以用angluar-ui-router插件,它允许你用multiple views嵌套,随意组建任何复杂页面。

Angular 就可以了,指令,然后 templateUrl

Django下可以加载的

{% extends "nav_generic.html" %}

类似于这样,各种框架的templates里面应该都有自己对应的部分,你也可以自己写一个全局的。

jquery load怎么样?效果还可以,只是复用不太好。

这需求解决方案就是模板引擎啦,适合后端来处理

不考虑后端的话,带模板的框架不是都可以?Angular,React等

哪怕是纯粹的前端渲染,模板复用也不是什么很难的问题吧

服务器如果支持Server Side Includes的话,直接在页面里用<!--include virtual="header.html"-->的方式就可以。文件后缀要用.shtml

这跟前后端分离没什么关系吧,这属于前端模块化开发的范畴,webpack,browserify这类前端工具是比较成熟的解决方案

seajs 模块化开发

看你要不要静态化,如果不用,用include很好,如果要,那用shtml技术

前一段时间处理过header 和footer,就它来说因为针对SEO优化 ,处理方式是用gulp 把编译出来的文件,放到后端模板管理后台,(后端做了个SEO处理)为什么要编译:因为页头页脚js css都是分离出来的 。

说几个思路吧,我大概想到三个,工具,前端,后端
dreamweave有一个模板功能,比如把head.htm设为模板,在各个 页面信用模板,可能现在都不用dw了,囧
前端可以用iframe在各个页面引入公用页面

后端很好解决,php的include
话说大主的的第一个网站不知道这些分开写的,后面页脚改了好多次,10多个页面囧死了

新手上路,请多包涵

纯前端层面,必须借助构建工具啊 试试fis

如果纯前端层面的话有很多办法啊,最近就在用鹅厂的artTemplate

如果硬要使用前端代码去做一些后端模板很容易就可以完成的事情,可以尝试使用 jade;
不过个人建议还是直接使用后端模板来处理这个需求,这样可维护性和性能都要好很多。

首先是回答问题的部分,
具体可以参考我的一个问题gulp如何连接html文件
当然了,借助grunt或者gulp之类的工具是非常容易就可以达到题主想要的效果
刚看了一下,@Chei怯 的回答使用gulp-file-include是更合理的解决方案

最高赞答案说得很很好,不过我还是打算插一脚
@hsfzxjy 的回答中有一点,我并不认同

首先我们要承认一点:现代网站中,基本上都是没有静态页面的。
基本没有而已,像很多人借github搭个静态博客还是很常见的

这种情况就是纯静态页面了

之前个人就非常热衷把静态页面扔上服务器
像在github搭的静态博客之类的
也试过把静态页面小游戏放上空间,然后用微信打开转给朋友玩的这类蠢事
就连之前公司的官网由于时初创实在也没有什么内容和改动频率较小的缘故
也被我用静态页面快速解决了
有两个原因
一是内容实在简单,根本没必要服务器
二是实在太懒,也不想去搭服务器

嗯,,就是这样,,表达一下,我并不是想撕逼呢= =

如果是非框架的话 jquery.load('footer.html'),是个不错的选择

宣传栏