nodejs抓取动态网页(网上提了个问:Express4开发的动态页面访问好慢的说?)
优采云 发布时间: 2021-11-23 01:14nodejs抓取动态网页(网上提了个问:Express4开发的动态页面访问好慢的说?)
上周在MOOC网站问了一个问题:Express4开发的动态页面访问有多慢?不幸的是,我没有得到可行的答案。周末折腾了一下,把小站(花满楼)的所有页面都静止了;仔细想想,这并不是一个特别标准的做法。, 不过折腾了这么久,终于有了解决这个问题的办法,还是有些欣慰的;
一开始页面是动态的,由jade模板渲染出来的,但是不明白为什么不管页面的内容,打开都需要至少一秒。. .
; 后来特地做了一个站点作为静态资源站,缓存和gzip(Nodejs搭建静态资源服务器和文件上传);OK,现在静态资源没有大问题;但是页面打开速度不理想,那就后台再按一下,来app.use(compress()); 事实证明,没有明显的效果;刚学Nodejs就郁闷,所以遇到这个无语的问题,百度了好久,哈哈。. . 最后,我只想到了一种方法。参考静态资源站点,将jade编译成html,将动态页面转成静态资源。它会像加载静态资源一样快吗?答案是肯定的!!!
就我的博客站点而言,我现在面临两个问题:一是直接编译原玉保留动态数据;另一种是去除动态数据编译成html,在ajax页面加载后请求数据;我选择前者,因为它可以在静态页面上保持最新的数据,而后者是js渲染的,对SEO很不利;哈哈,其实这两种方法我都没有用过,因为在这个层面上,在express框架中,没听说过这种方法,自然下不来,只是一个理想的可行方案;
我该怎么办?好吧,原谅我选择放弃express的内置模板。经过一番整理,Gulp(gulp-jade模块)直接将那些jade全部编译成html(前端自动化的神器——Gulp)。我想是这样。编译后的 html 用作类似模板的模块。数据还是像之前一样在路由中取,将获取到的数据作为变量传递给html模板模块对应的接口,然后返回的html生成为一个真正的静态页面,这样,在路由器不变的情况下,直接生成原玉到对应目录;如上所述,页面需要像静态资源一样加载才能快速;
Gulpfile.js
1 var jade=require('gulp-jade');
2
3 gulp.task('jade',function() {
4 gulp.src('./views/bokeDetail.jade')
5 .pipe(jade({pretty:true}))
6 .pipe(gulp.dest('./public/famanoder/'));
7 });
bokeDetail.templ.js
1 var html=function(id,title,subtitle,time,from,contents){
2 //传递动态数据
3 return ''+动态数据+'';
4 }
5 //片段,实际情况而定
bokeDetail.js(路由器)
1 //......
2 //引入对应静态模块
3 var boketempl=require('./templs/bokeDetail.templ.js);
4
5 //依旧读取数据
6 //传递数据:如,id,title,content,comments
7 //生成静态页面到指定目录
8 function createStaticPage(id,title,content,comments,fn){
9 var path='./public/famanoder/';
10 var html=boketempl(id,title,content,comments);
11 var ws=fs.createWriteStream(path+id+'.html');
12 ws.write(html,function(err) {
13 console.log('writePage:'+path+id+'.html');
14 fn&&fn();
15 });
16 ws.on('drain',function() {
17 ws.end();
18 });
19 }
ok,程序执行后会生成静态页面,动态数据放到public下的famanoder目录下;下面是将响应直接指向bokeDetail.js(路由器)中上面生成的静态页面;
1 var pathname=url.parse(req.url).pathname;
2 var realpath='./public/famanoder/'+pathname.substr(pathname.lastIndexOf('/')+1)+'.html';
3 var type='text/html';
4 var extname='html';
5 fs.exists(realpath,function(exist){
6 if(!exist){console.log(101);
7 res.writeHead(404,{
8 'content-type':'text/plain'
9 });
10 res.write('The Resourse '+pathname+' was Not Found!');
11 res.end();
12 }else{
13 fs.readFile(realpath,'binary',function(err,file){
14 console.log(11);
15 if(err){
16 res.writeHead(500,{
17 'content-type':'text/plain'
18 });
19 res.end();
20 }
21 if(extname.match(config.fileMatch)){
22 var expires=new Date();
23 expires.setTime(expires.getTime()+config.maxAge*1000);
24 res.setHeader('Expires',expires.toUTCString());
25 res.setHeader('cache-control','max-age='+config.maxAge);
26 }
27 fs.stat(realpath,function(err,stat){
28 var lastModified=stat.mtime.toUTCString();
29 res.setHeader('Last-Modified',lastModified);
30
31 if(req.headers['if-modified-since']&&lastModified==req.headers['if-modified-since']){
32 console.log(0);
33 res.writeHead(304,{
34 'content-type':type
35 });
36 res.end();
37 }else{
38 var raw=fs.createReadStream(realpath);
39 var acceptEncoding=req.headers['accept-encoding']||'';
40 var matched=extname.match(/css|js|html/ig);
41 if(matched&&acceptEncoding.match(/\bgzip\b/)){
42 console.log(1);
43 res.writeHead(200,{
44 'content-type':type,
45 'Content-Encoding':'gzip'
46 });
47 raw.pipe(zlib.createGzip()).pipe(res);
48 }else if(matched&&acceptEncoding.match(/\bdeflate\b/)){
49 console.log(2);
50 res.writeHead(200,{
51 'content-type':type,
52 'Content-Encoding':'deflate'
53 });
54 raw.pipe(zlib.createDeflate()).pipe(res);
55 }else{
56 console.log(3);
57 res.writeHead(200,{
58 'content-type':type
59 });
60 raw.pipe(res);
61 }
62 }
63 });
64 });
65 }
66 });
再次访问详细信息页面,查看秒数是否打开。纯静态,路由没变,url没变,维护也很简单。只需更改 bokeDetail.templ.js; 没办法,可能在英雄眼中吧。这是傻瓜式,只是让你发笑;与此方法类似,网站的所有页面现在都是静态的,并且 SEO 得到充分照顾;
嗯,其实还有一个很重要的问题:就博客的细节而言,如果博客数量很多,如何批量转移?其实我在编辑和提交博客的时候顺便生成了一个静态页面。为了让详情页快点。. .
; 问题来了,如果我之前有成百上千的博客(当然,我的小前端远没有达到这样的丰硕成果),我一定不能再编辑提交每个博客;吓死宝宝了,别急,新建一个update.js直接批量生成,非常快!
<p> 1 Artical
2 .find({}).exec(function(err,docs) {
3 update(err,docs);
4 });
5
6 function update(err,docs) {
7 err&&console.log(err);
8 for(var i=0;i