JavaScript的History API使搜索引擎抓取AJAX内容


Posted in Javascript onDecember 07, 2015

大家在浏览Facebook的相册时有没有发现,页面局部刷新的同时地址栏的地址也改变了,而且不是hash的方式。它使用的就是HTML5 history新增的几个API,作为window的一个全局变量,在HTML4的时代history已不是什么新鲜的事物了。我们经常使用的就有 history.back()以及history.go() 。

我一直以为没有办法做到,直到前两天看到了Discourse创始人之一的Robin Ward的解决方法,不禁拍案叫绝。

JavaScript的History API使搜索引擎抓取AJAX内容

Discourse是一个论坛程序,严重依赖Ajax,但是又必须让Google收录内容。它的解决方法就是放弃井号结构,采用 History API。

所谓 History API,指的是不刷新页面的情况下,改变浏览器地址栏显示的URL(准确说,是改变网页的当前状态)。这里有一个例子,你点击上方的按钮,开始播放音乐。然后,再点击下面的链接,看看发生了什么事?

JavaScript的History API使搜索引擎抓取AJAX内容

地址栏的URL变了,但是音乐播放没有中断!

History API 的详细介绍,超出这篇文章的范围。这里只简单说,它的作用就是在浏览器的History对象中,添加一条记录。

window.history.pushState(state object, title, url);

上面这行命令,可以让地址栏出现新的URL。History对象的pushState方法接受三个参数,新的URL就是第三个参数,前两个参数都可以是null。

window.history.pushState(null, null, newURL);

目前,各大浏览器都支持这个方法:Chrome(26.0+),Firefox(20.0+),IE(10.0+),Safari(5.1+),Opera(12.1+)。

下面就是Robin Ward的方法。

首先,用History API替代井号结构,让每个井号都变成正常路径的URL,这样搜索引擎就会抓取每一个网页。

example.com/1
 

example.com/2
 

example.com/3

然后,定义一个JavaScript函数,处理Ajax部分,根据网址抓取内容(假定使用jQuery)。

 function anchorClick(link) {
 
var linkSplit = link.split('/').pop();
 

$.get('api/' + linkSplit, function(data) {
 


$('#content').html(data);
 

});
 
} 

再定义鼠标的click事件。

$('#container').on('click', 'a', function(e) {
 

window.history.pushState(null, null, $(this).attr('href'));
 

anchorClick($(this).attr('href'));
 

e.preventDefault();
 
});

还要考虑到用户点击浏览器的"前进 / 后退"按钮。这时会触发History对象的popstate事件。

 window.addEventListener('popstate', function(e) {  
 
anchorClick(location.pathname); 
 
}); 

定义完上面三段代码,就能在不刷新页面的情况下,显示正常路径URL和AJAX内容。

最后,设置服务器端。

因为不使用井号结构,每个URL都是一个不同的请求。所以,要求服务器端对所有这些请求,都返回如下结构的网页,防止出现404错误。

  <html>
 
<body>
 


<section id='container'></section>
 


<noscript>
 



... ...
 


</noscript>
 

</body>
 
</html>

仔细看上面这段代码,你会发现有一个noscript标签,这就是奥妙所在。

我们把所有要让搜索引擎收录的内容,都放在noscript标签之中。这样的话,用户依然可以执行AJAX操作,不用刷新页面,但是搜索引擎会收录每个网页的主要内容!                  

Javascript 相关文章推荐
javascript  Error 对象 错误处理
May 18 Javascript
JQuery扩展插件Validate—6 radio、checkbox、select的验证
Sep 05 Javascript
css+js实现部分区域高亮可编辑遮罩层
Mar 04 Javascript
js动态删除div元素基本思路及实现代码
May 08 Javascript
纯js实现div内图片自适应大小(已测试,兼容火狐)
Jun 16 Javascript
bootstrap3 兼容IE8浏览器!
May 02 Javascript
详解原生JavaScript实现jQuery中AJAX处理的方法
May 10 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
May 24 Javascript
前端框架Vue.js构建大型应用浅析
Sep 12 Javascript
浅谈React中组件间抽象
Jan 27 Javascript
详解如何解决Vue和vue-template-compiler版本之间的问题
Sep 17 Javascript
vue+element_ui上传文件,并传递额外参数操作
Dec 05 Vue.js
JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题
Dec 07 #Javascript
小巧强大的jquery layer弹窗弹层插件
Dec 06 #Javascript
使用jQuery+EasyUI实现CheckBoxTree的级联选中特效
Dec 06 #Javascript
javascript字符串函数汇总
Dec 06 #Javascript
win7下安装配置node.js+express开发环境
Dec 06 #Javascript
分享使用AngularJS创建应用的5个框架
Dec 05 #Javascript
如何利用AngularJS打造一款简单Web应用
Dec 05 #Javascript
You might like
ecshop 订单确认中显示省市地址信息的方法
2010/03/15 PHP
php下安装配置fckeditor编辑器的方法
2011/03/02 PHP
PHP以及MYSQL日期比较方法
2012/11/29 PHP
zf框架的Filter过滤器使用示例
2014/03/13 PHP
浅谈PDO的rowCount函数
2015/06/18 PHP
PHP实现文件上传与下载
2020/08/28 PHP
广告代码静态化js通用函数
2007/05/09 Javascript
js,jQuery 排序的实现代码,网页标签排序的实现,标签排序
2011/04/27 Javascript
js鼠标点击事件在各个浏览器中的写法及Event对象属性介绍
2013/01/24 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
2015/09/23 Javascript
微信小程序 css使用技巧总结
2017/01/09 Javascript
用JavaScript实现让浏览器停止载入页面的方法
2017/01/19 Javascript
jquery实现图片轮播器
2017/05/23 jQuery
基于vue的换肤功能的示例代码
2017/10/10 Javascript
在vue中v-bind使用三目运算符绑定class的实例
2018/09/29 Javascript
Vue 表情包输入组件的实现代码
2019/01/21 Javascript
[13:18]《一刀刀一天》之DOTA全时刻21:详解TI新赛制 A队再露獠牙
2014/06/24 DOTA
python开发的小球完全弹性碰撞游戏代码
2013/10/15 Python
python通过ftplib登录到ftp服务器的方法
2015/05/08 Python
Python字符串格式化%s%d%f详解
2018/02/02 Python
结束运行python的方法
2020/06/16 Python
美国学校用品、教室和教学商店:Discount School Supply
2018/04/04 全球购物
以实惠的价格轻松租车,免费取消:Easyrentcars
2019/07/16 全球购物
C++:局部变量能否和全局变量重名
2014/03/03 面试题
经典c++面试题五
2014/12/17 面试题
医科学校毕业生自荐信
2013/11/09 职场文书
4s店总经理岗位职责
2013/12/31 职场文书
高中教师考核方案
2014/05/18 职场文书
交通事故委托书范本(2篇)
2014/09/21 职场文书
与死神共舞观后感
2015/06/15 职场文书
2021-4-5课程——SQL Server查询【3】
2021/04/05 SQL Server
python中print格式化输出的问题
2021/04/16 Python
python scrapy简单模拟登录的代码分析
2021/07/21 Python
什么是动态刷新率DRR? Windows11动态刷新率功能介绍
2021/11/21 数码科技
spring cloud eureka 服务启动失败的原因分析及解决方法
2022/03/17 Java/Android
MSSQL基本语法操作
2022/04/11 SQL Server