如何让搜索引擎抓取AJAX内容解决方案


Posted in PHP onAugust 25, 2014

越来越多的网站,开始采用"单页面结构"(Single-page application)。

整个网站只有一张网页,采用Ajax技术,根据用户的输入,加载不同的内容。

如何让搜索引擎抓取AJAX内容解决方案

这种做法的好处是用户体验好、节省流量,缺点是AJAX内容无法被搜索引擎抓取。举例来说,你有一个网站。

http://example.com

用户通过井号结构的URL,看到不同的内容。

http://example.com#1
http://example.com#2
http://example.com#3

但是,搜索引擎只抓取example.com,不会理会井号,因此也就无法索引内容。

为了解决这个问题,Google提出了"井号+感叹号"的结构。

http://example.com#!1

当Google发现上面这样的URL,就自动抓取另一个网址:

http://example.com/?_escaped_fragment_=1

只要你把AJAX内容放在这个网址,Google就会收录。但是问题是,"井号+感叹号"非常难看且烦琐。Twitter曾经采用这种结构,它把

http://twitter.com/ruanyf

改成

http://twitter.com/#!/ruanyf

结果用户抱怨连连,只用了半年就废除了。

那么,有没有什么方法,可以在保持比较直观的URL的同时,还让搜索引擎能够抓取AJAX内容?

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

如何让搜索引擎抓取AJAX内容解决方案

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

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

如何让搜索引擎抓取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操作,不用刷新页面,但是搜索引擎会收录每个网页的主要内容!

PHP 相关文章推荐
一个PHP日历程序
Dec 06 PHP
PHP容易被忽略而出错陷阱 数字与字符串比较
Nov 10 PHP
第七章 php自定义函数实现代码
Dec 30 PHP
PHP教程之PHP中shell脚本的使用方法分享
Feb 23 PHP
php生成圆角图片的方法
Apr 07 PHP
详谈PHP编码转换问题
Jul 28 PHP
Laravel 5.5官方推荐的Nginx配置学习教程
Oct 06 PHP
PHP守护进程化在C和PHP环境下的实现
Nov 21 PHP
PHP设计模式之建造者模式定义与用法简单示例
Aug 13 PHP
PHP+Apache实现二级域名之间共享cookie的方法
Jul 24 PHP
laravel dingo API返回自定义错误信息的实例
Sep 29 PHP
PHP CURL实现模拟登陆并上传文件操作示例
Jan 02 PHP
使用php方法curl抓取AJAX异步内容思路分析及代码分享
Aug 25 #PHP
简单分析ucenter 会员同步登录通信原理
Aug 25 #PHP
ThinkPHP调用common/common.php函数提示错误function undefined的解决方法
Aug 25 #PHP
ThinkPHP查询返回简单字段数组的方法
Aug 25 #PHP
php防止伪造数据从地址栏URL提交的方法
Aug 24 #PHP
php批量删除数据库下指定前缀的表以prefix_为例
Aug 24 #PHP
一个图片地址分解程序(用于PHP小偷程序)
Aug 23 #PHP
You might like
JS与PHP向函数传递可变参数的区别实例代码
2011/05/18 PHP
在WordPress的文章编辑器中设置默认内容的方法
2015/12/29 PHP
详解PHP文件的自动加载(autoloading)
2018/02/04 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
比较全面的event对像在IE与FF中的区别 推荐
2009/09/21 Javascript
jquery实现点击消失的代码
2014/03/03 Javascript
微信分享的标题、缩略图、连接及描述设置方法
2014/10/14 Javascript
简介JavaScript中的getSeconds()方法的使用
2015/06/10 Javascript
javascript封装 Cookie 应用接口
2015/08/07 Javascript
Bootstrap每天必学之折叠(Collapse)插件
2016/04/25 Javascript
简单实现js选项卡切换效果
2017/02/09 Javascript
Bootstrap表单简单实现代码
2017/03/06 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
2017/04/18 Javascript
使用electron将vue-cli项目打包成exe的方法
2018/09/29 Javascript
Iview Table组件中各种组件扩展的使用
2018/10/20 Javascript
详解React 服务端渲染方案完美的解决方案
2018/12/14 Javascript
微信小程序实现的动态设置导航栏标题功能示例
2019/01/31 Javascript
VUE解决 v-html不能触发点击事件的问题
2019/10/28 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
2020/12/09 Javascript
[52:12]FNATIC vs Infamous 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
[01:06:43]完美世界DOTA2联赛PWL S3 PXG vs GXR 第二场 12.19
2020/12/24 DOTA
Python version 2.7 required, which was not found in the registry
2014/08/26 Python
Python计算程序运行时间的方法
2014/12/13 Python
python从网络读取图片并直接进行处理的方法
2015/05/22 Python
基于Django模板中的数字自增(详解)
2017/09/05 Python
pytorch + visdom CNN处理自建图片数据集的方法
2018/06/04 Python
Python3.5 Pandas模块之Series用法实例分析
2019/04/23 Python
Django框架中间件(Middleware)用法实例分析
2019/05/24 Python
python代码实现将列表中重复元素之间的内容全部滤除
2020/05/22 Python
python进行二次方程式计算的实例讲解
2020/12/06 Python
美国南部最大的家族百货公司:Belk
2017/01/30 全球购物
Lululemon加拿大官网:加拿大知名体育服装零售商
2019/04/12 全球购物
全国爱牙日活动总结
2015/02/05 职场文书
运动会闭幕式主持词
2015/07/01 职场文书
JavaScript实现显示和隐藏图片
2021/04/29 Javascript
Linux中各个目录的作用与内容
2022/06/28 Servers