探讨webapp的SEO难题(上)
前言


.net解决思路
<script type="text/blade_config">
{
url: 'restful/index',
template: 'indexTmpt'
}
</script>
<script id="indexTmpt" type="text/blade_template">
<ul>
<% for(var i = 0, len = data.length; i < len; i++) { %>
<li><%=data[i].name %></li>
<% } %>
</ul>
</script>
//模拟数据返回
data = [
{id: 0, name: 'item_0'},
{id: 1, name: 'item_1'},
{id: 2, name: 'item_2'}
]
这里期待的webapp处理逻辑:
期待的seo处理逻辑:
为什么不直接服务器吐出完整html?
这个方案的代价是:
.net解析javascript

① 解析页面的config信息,取出url以及template
② 根据url发出请求返回数据,这里由于是局域网应该很快
③ 解析template,根据data生成静态html
④ 其它处理,返回客户端
模拟处理逻辑
我们这里略去url请求一步,假设数据已经返回,否则这里又要写.net程序
var data = [
{id: 0, name: 'item_0'},
{id: 1, name: 'item_1'},
{id: 2, name: 'item_2'}
];
这里的模板字符串为:
var template = [
'<ul>',
'<% for(var i = 0, len = data.length; i < len; i++) { %>',
'<li><%=data[i].name %></li>',
'<% } %>',
'</ul>'
].join('');
然后我们要做的就是解析这个模板,生成对应的模板解析函数,这里是调试代码:
var data = [
{ id: 0, name: 'item_0' },
{ id: 1, name: 'item_1' },
{ id: 2, name: 'item_2' }
]; var template = [
'<ul>',
'<% for(var i = 0, len = data.length; i < len; i++) { %>',
'<li><%=data[i].name %></li>',
'<% } %>',
'</ul>'
].join(''); var templateHandler = function (text, data) { var noMatch = /(.)^/; var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
}; var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; var templateSettings = {
evaluate: /<%([\s\S]+?)%>/g,
interpolate: /<%=([\s\S]+?)%>/g,
escape: /<%-([\s\S]+?)%>/g
}; var render;
settings = templateSettings;
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g'); var index = 0;
var source = "__p+='";
text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function (match) { return '\\' + escapes[match]; }); if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n"; if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n"; return source; try {
render = new Function(settings.variable || 'obj', source);
} catch (e) {
e.source = source;
throw e;
} if (data) return render(data);
var template = function (data) {
return render.call(this, data);
}; template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; return template;
} templateHandler(template, data)
首次调试爆了很多错误,而且服务器端的调试比较费力,错了只能靠经验去猜测

这里返回的是需要构造成函数的字符串,但是我们看到我们的“ul”等标签被吃掉了!!!
var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};
with(obj||{}){
__p+='';
for(var i = 0, len = data.length; i < len; i++) {
__p+=''+
((__t=(data[i].name ))==null?'':__t)+
'';
}
__p+='';
}
return __p;
我们这里一旦调用就抛了一个错误,这个时候一般是模板或者传入数据出错了,可惜的是他是对其中一段语法不可解析!这里从侧面反映出一个问题:
该方法若是模板出错会导致程序无法运行,如果是node的话很可能就crash了!
PS:这里由于CLR4解析javascript的时候字符串的replace遇到正则时有问题,在此逗留3小时,这里把我搞惨了,定位就很久最后还得重写模板解析!!!
var data = [
{ id: 0, name: 'item_0' },
{ id: 1, name: 'item_1' },
{ id: 2, name: 'item_2' }
]; var template = [
'<ul>',
'<% for(var i = 0, len = data.length; i < len; i++) { %>',
'<li><%=data[i].name %></li>',
'<% } %>',
'</ul>'
].join(''); var templateHandler = function (text, data) { var noMatch = /(.)^/; var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
}; var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; var templateSettings = {
evaluate: /<%([\s\S]+?)%>/g,
interpolate: /<%=([\s\S]+?)%>/g
}; var render;
var settings = templateSettings; var matcher = new RegExp([
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g'); var index = 0;
var source = "__p+='";
var _text = text; var _treg; while (1) { var matcher = new RegExp([
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g'); (function () {
_treg = matcher.exec(_text)
})(); var t_str = _treg[0];
var t_len = t_str.length;
var t_index = _treg.index; source += _text.slice(index, t_index).replace(escaper, function (match) { return '\\' + escapes[match]; });
_text = _text.slice(t_index + t_len); if (_treg[2]) {
source += "';\n" + _treg[2] + "\n__p+='";
}
if (_treg[1]) {
source += "'+\n" + _treg[1] + "\n'";
}
if (_text.length == 0) break; }
source += "';\n"; if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n"; try {
render = new Function(settings.variable || 'obj', source);
} catch (e) {
e.source = source;
throw e;
} //return source; if (data) return render(data);
var template = function (data) {
return render.call(this, data);
}; template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; return template;
} templateHandler(template, { data: data })
正确的代码

我这里使用生命在调试啊!!!因为服务器解析javascript时候,很多东西都不支持,感觉有点回到了c++!!!
小结
这里字符串解析成功,我们这部分也就告一段落了,本身.net方案也不是这次的重点,这里提供基本思路各位自己去看看吧,总之调试很坑
下期预告
对javascript来说,nodeJS自然是亲爹,我们这次的主要方案其实是基于nodeJS的,这里的期望:
① 用户请求过来时候首先判断是否为网络爬虫
② 网络爬虫访问seo/index.html,用户访问webapp/index.html
当然,我们做demo时候不会这么麻烦,我们直接为其添加一个seo=true的标志位在url即可
nodeJS实现SEO的方案重点依旧在首屏渲染,我们这里首先基于blade做两个页面,然后以此扩展seo的方案
当然此块内容有点小复杂,加之,小钗对nodeJS停留在学习阶段,这块需要学习,而且最近有些其它事情扰心,暂时便搁置了
这块的内容可能与RapidJS(clouda前身)有关,有兴趣的同学可以先去看看
文中有误请您指出,若您对webapp的seo有什么好的想法请留言
探讨webapp的SEO难题(上)的更多相关文章
- DTCMS添加文章,将tags标签的值赋到SEO关键词上,以及将摘要的值赋到SEO描述
将tags标签的值赋到SEO关键词上 admin\article_edit.aspx中 $(function () { 方法中加上 //tags的值赋到SEO关键词上 $("#txtTag ...
- SEO优化上首页之搜索引擎排名规则
搜索引擎建立索引的网页数以万亿计,用户搜索的关键词也是海量,如果每个用户提交搜索请求后,搜索引擎都去数以万亿的索引中重新排名网页,效率将非常低下.根据2-8法则,80%是查询是集中在相同的20%内容上 ...
- SEO优化上首页之搜索引擎原理内容处理与索引
上文<搜索引擎原理SEO优化上首页之蜘蛛Spider>详细介绍了蜘蛛的分类.抓取入口.抓取策略和更新策略.搜索引擎已把页面抓取回来,接下来是解析页面内容,主要包含判断页面类型.提取页面主题 ...
- SEO优化上首页之搜索引擎蜘蛛Spider原理
Spider,蜘蛛,又名网页网络爬虫.网络机器人,是按照一定策略不断抓取互联网网页的特定程序.蜘蛛抓回的页面创建索引后参与排名,等待用户检索.为了网站优化自然排名上首页,精灵儿工作室下面详细剖析Spi ...
- SEO优化上首页之搜索引擎原理简要
搜索引擎(Search Engine)是特定的计算机程序,它根据一定的策略.从互联网上搜集信息,对信息进行处理后,为用户提供检索服务,并将用户结果展示给用户. 搜索引擎优化(Search Engine ...
- SEO优化上首页之搜索引擎作弊案例与反作弊原理
搜索引擎流量价值巨大,有不少人专门研究排名机制,利用搜索引擎漏洞作弊,寻求快速提高网站排名,进而获取更多的流量和利益,甚至有的网站优化公司专门提供作弊服务.搜索引擎为了杜绝这种情况,必须能过滤大量垃圾 ...
- SEO优化上首页之搜索引擎用户需求理解
经过前面<搜索引擎原理SEO优化上首页之网络蜘蛛Spider>和<搜索引擎原理SEO优化上首页之内容处理与创建索引>介绍,搜索引擎已经完成页面抓取和分析,并把原始页面.索引等信 ...
- Safari配置WebApp----添加启动图和桌面图标让你的WebApp在ios设备上体验如原生一样
现在很多开发者的Web应用程序的设计样式和交互类似本机应用程序,例如,它的缩放比例适合iOS上的整个屏幕.当用户将其添加到主屏幕时,您可以通过使其看起来像本机应用程序一样,在iOS上为您的Web应用程 ...
- #翻译# 深入JavaScript的Unicode难题(上)
退一步说, JavaScript处理Unicode时有些怪异. 这篇文章会说明JS在Unicode上令人痛苦的部分, 然后提供解决方案, 并说明在未来的ECMAScript6中是如何改善这些问题的. ...
随机推荐
- ora-01652无法通过128(在表空间temp中)扩展temp段
今天提交请求后,提示ORA-01652: 无法通过 128 (在表空间 TEMP 中) 扩展 temp 段.最后通过ALTER DATABASE TEMPFILE '/*/*/db/apps_st/d ...
- A Simple OpenGL Shader Example II
A Simple OpenGL Shader Example II eryar@163.com Abstract. The OpenGL Shading Language syntax comes f ...
- OpenCASCADE Hidden Line Removal
OpenCASCADE Hidden Line Removal eryar@163.com Abstract. To provide the precision required in industr ...
- SmtpClient发邮件时为什么用MailMessage.From而不用MailMessage.Sender
今天在看C#高级编程(第9版)的时候,在768页看到这样的一段代码 SmtpClient sc = new SmtpClient(); sc.Host = "邮箱服务器地址"; M ...
- 深入理解javascript中的动态集合——NodeList、HTMLCollection和NamedNodeMap
× 目录 [1]NodeList [2]HTMLCollection [3]NamedNodeMap[4]注意事项 前面的话 一说起动态集合,多数人可能都有所了解.但是,如果再深入些,有哪些动态集合, ...
- .Net 转战 Android 4.4 日常笔记(7)--apk的打包与反编译
apk(android package)就是我们安卓系统的安装文件,可以在模拟器和手机中直接打开安装,从项目中打包apk有几种方式可取 一.最简单的方法(类似我们的winfrom) 只要我们调试或者运 ...
- MySQL utf8mb4 字符集:支持 emoji 表情符号
转载地址:http://www.linuxidc.com/Linux/2013-05/84360.htm 我用他的方法解决了问题,亲测可用,不要用Nnvicat for Mysql去查询编码,在服务器 ...
- 探讨Android中的内置浏览器和Chrome
1.Android默认浏览器和Chrome的区别 Android出厂自带的浏览器:安卓WebKit浏览器,也成内置浏览器或者默认浏览器. 安卓WebKit不是Chrome.Chrome浏览器在它的用户 ...
- react-native 学习之TextInput组件篇
/** * Sample React Native App * https://github.com/facebook/react-native */ 'use strict'; import Rea ...
- js 把数字转成2 ,8,16进制的方法
直接上代码 <!DOCTYPE html> <html> <body> <script> var myNumber = 128; document.wr ...