思路
- 将 getitem.html 中
jQuery(document).ready(function(){... })
方法中的内容,在服务端或爬虫端执行掉,执行完成之后,依赖于爬虫,生成一个 reload dom 完成的静态 html 文件; - 将生成出来的静态 html 文件部署到 CDN 上,完成全页面静态化的操作;
针对商品详情页的全页面静态化实践
编写 phantomjs 脚本 getitem.js
-
var page =
require(
"webpage").
create();
-
var fs =
require(
"fs");
-
page.
open(
"http://localhost/resources/getitem.html?id=1",
function(status) {
-
console.
log(
"status = " +
status);
-
setTimeout(
function() {
-
fs.
write(
"getitemphantom.html", page.content,
"w");
-
phantom.
exit();
-
},
1000);
-
});
修改 getitem.html 中的内容
- 添加隐藏域;
<input type="hidden" id="isInit" value="0" />
- 添加几个全局函数,其实就是使用 Balking 模式,使得由无头浏览器执行完,并且生成出来的静态 html 页面,由用户再去打开的时候 ,不会再发 ajax 请求给后端;
-
function
hasInit(
) {
-
var isInit = $(
"#isInit").
val();
-
return isInit;
-
}
-
-
function
setHasInit(
) {
-
$(
"#isInit").
val(
"1");
-
}
-
-
function
initView(
) {
-
var isInit =
hasInit();
-
if(isInit ==
"1") {
-
return;
-
}
-
-
/**
-
* ajax 请求对应的域是本地文件,请求的服务器的域名是 localhost,能请求,能响应,但是 ajax 的回调函数认定域不同,是不安全的,
-
* 因此会报错,并且走不到 ajax 的 success 回调中;
-
* 解决方案:在 Response 的 Header 中增加字段 Access-Control-Allow-Origin:*
-
*/
-
$.
ajax({
-
type:
"GET",
-
url:
"http://"+g_host+
"/item/get",
-
data:{
-
"id":
getQueryString(
"id")
-
},
-
// 允许跨域的授信请求,和后端 @CrossOrigin(allowCredentials = "true") 呼应,
-
// 使 Session 变成跨域可授信(从 Session 中可以取到短信验证码)
-
xhrFields:{
withCredentials:
true},
-
success:
function(
data){
-
if(data.
status ==
"success"){
-
g_itemVO = data.
data;
-
reloadDom();
-
setInterval(reloadDom,
1000);
-
setHasInit();
-
}
else{
-
alert(
"获取商品详情失败,原因为:" + data.
data.
errMsg);
-
}
-
},
-
error:
function(
data){
-
alert(
"获取商品详情失败,原因为:" + data.
responseText);
-
}
-
});
-
}
- 修改 getitem.js
-
var page =
require(
"webpage").
create();
-
var fs =
require(
"fs");
-
page.
open(
"http://localhost/resources/getitem.html?id=1",
function(status) {
-
console.
log(
"status = " +
status);
-
var isInit =
"0";
-
setInterval(
function() {
-
if(isInit !=
"1") {
-
page.evaluate(
function(){
-
initView();
-
});
-
isInit = page.evaluate(
function(){
-
return hasInit();
-
});
-
}
else {
-
fs.
write(
"getitemphantom.html", page.content,
"w");
-
phantom.
exit();
-
}
-
},
1000);
-
});
- 执行 getitem.js,注意,此时修改过的 getitem.html 必须放到 Nginx 上去,执行成功后,会生成 getitemphantom.html,其中隐藏域的 value 已经设置成了 1;
- 用户如果用浏览器打开 getitemphantom.html 会发现没有网络请求,这是一个完全静态化的 html 页面,把这个页面放到 CDN 上去,就可以在 CDN 层面完全命中,不会再有哪怕 ajax 的请求打到源站服务器上去了;
-
lixinlei
@pc
:~/application/phantomjs-
2.1.
0-linux-x86_64
$ bin/phantomjs js/getitem.js
-
status = success