Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

模板的逆解析

  在模板式开发中,我们做的最多的事就是把数据通过模板印铸成我们需要的格式。如果考虑SEO,我们就必须在后端来执行印铸。为了避免数据的重复传输,前端就可能需要从这个已经印铸出的数据通过同样的模板,反向解析出原始数据,这就是模板的逆解析。
  逆解析,实际上就是印铸的反函数。印铸是将抽象数据通过模板转换成结构化的数据实体,而逆解析是将结构化的数据实体通过模板转换成抽象数据。比如我们操作的例子是HTML,那么逆解析就是传入HTML,得到一个JavaScript对象。
  下面是个逆解析的程序例子 <script>
//模板构造器
function Template(template){
  if(typeof template=="object")template=template.innerHTML;
  this.template=template;
  //顺序保存字段名
  var fields=this.fields=[];
  //构造模式串
  this.pattern=new RegExp(
    template.replace(/\{(\w+)\}|(\s+)|(\W)/g,function($,a,b,c){
      if(a)return fields.push(a),"([\\s\\S]*?)"; //对数据使用获取匹配
      if(b)return "\\s*"; //无视多余空白
      //对其它字符使用转义,以确保在正则表达式中正确存在
      if(c)return "\\u"+("000"+c.charCodeAt(0).toString(16)).slice(-4);
    })
  ,"ig");
};
//模板构造器原型方法
Template.prototype.abstract=function(text){
  //使用pattern去匹配,并收集数据
  for(var i,m,o,r=[];o={},m=this.pattern.exec(text);r.push(o))
    for(i=0;i<this.fields.length;i++)o[this.fields[i]]=m[i+1];
  return r;
};
onload=function(){
  //准备模板对象
  var listTemplate=new Template(template);
  //抽取数据
  console.log(listTemplate.abstract(list.innerHTML));
};
</script>
<!--模板-->
<script type="text/x-template" id="template">
  <li><time>{time}</time> <a href="{link}">{title}</a></li>
</script>
<!--服务器印铸出的数据-->
<ul id="list">
  <li><time>前天</time> <a href="#1">条目1</a></li>
  <li><time>昨天</time> <a href="#2">条目2</a></li>
  <li><time>今天</time> <a href="#3">条目3</a></li>
</ul>
  对于纯数据模板,我们总能找到一个模式串来执行逆解析。而那些嵌入了逻辑的模板,他们就未必存在相应的逆。这也是为什么我一直强调不要对模板嵌入逻辑的原因之一。
  逆解析的作用是非常强大的,前端很有可能对同一个数据多次使用,这些数据完全没有多次传输它的必要。如果只是基于程序,也许我们可以直接从服务器请求一个JSON来得到数据,但考虑SEO的话就不得不把数据输出到原始源中。所以从HTML中把数据抽取出来是很重要的。
  上面只是一个最简单的例子,实际情况可能要复杂的多,甚至低版本浏览器上的兼容性差异都会造成影响。
网名:
54.226.58.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^