VUE项目SEO优化思路以及实现

我们公司有个前台项目,但是使用了vue做成了一个SPA项目,我们都知道vue SPA项目的每一个路由跳转的页面都没有真实发起的请求。

我经常会在面试的时候问,为什么vue项目在搜索引擎优化这方面会有问题,这个问题其实是因为vue项目只有一个真实的可供浏览器访问的地址,因此百度蜘蛛每次的访问只会访问到“index.html”。同时,百度搜索引擎抓取这个思路涉及到一些nodejs服务器和Nginx服务器的知识。

一、整体思路

百度蜘蛛只会抓取网站的静态文件,因此不会抓取到前后端分离项目最终渲染的页面。因此我们需要让蜘蛛从服务器上抓取浏览器渲染完成的页面。经过搜索,我们知道有一种可以在服务器端运行的东西,叫“无头浏览器”,就是一个无界面的浏览器,可以用于页面的服务器端渲染,网页截图等工作。目前流行的服务器端渲染工具有“phantomjs”、基于node的 “puppeteer”等,我们选用的是“phantom.js”。

在此基础上如果我们在所有情况下都使用“phantomjs”渲染页面的话,显然不现实,不但会导致路由跳转在页面上无法操作,甚至还会导致服务器压力过大,基于此我们需要使用nginx通过判断是否是蜘蛛访问来进行转发,以此提高访问效率。

与此同时为了保障phantomjs服务的稳定,我们需要使用node进程管理工具“PM2”对服务进行管理

二、具体实现

        1 我们需要使用一台服务器安装基本的node服务,phantomjs服务,以及pm2工具,为了保障项目的正常运行,我们尽量不要选择项目同源服务器!

        2 安装完毕后 创建一个js 就命名为“spider.js”吧 内容如下



/*global phantom*/

"use strict";

// 单个资源等待时间,避免资源加载后还需要加载其他资源

var resourceWait = 500;

var resourceWaitTimer;

// 最大等待时间

var maxWait = 5000;

var maxWaitTimer;

// 资源计数

var resourceCount = 0;

// PhantomJS WebPage模块

var page = require('webpage').create();

// NodeJS 系统模块

var system = require('system');

// 从CLI中获取第二个参数为目标URL

var url = system.args[1];

// 设置PhantomJS视窗大小

page.viewportSize = {

    width: 1920,

    height: 1014

};

// 获取镜像

var capture = function(errCode){

    // 外部通过stdout获取页面内容

    console.log(page.content);

    // 清除计时器

    clearTimeout(maxWaitTimer);

    // 任务完成,正常退出

    setTimeout(phantom.exit(errCode), 1500);

};

// 资源请求并计数

page.onResourceRequested = function(req){

    resourceCount++;

    clearTimeout(resourceWaitTimer);

};

// 资源加载完毕

page.onLoadFinished = function(status) {

    if (status !== 'success'){

            return;

        }

    else{

        resourceWaitTimer = setTimeout(capture, resourceWait);  

    }  

  // Do other things here...

};

// 资源加载超时

page.onResourceTimeout = function(req){

    resouceCount--;

};

// 资源加载失败

page.onResourceError = function(err){

    resourceCount--;

};

page.onError = function(msg, trace) {

    var msgStack = ['ERROR: ' + msg];

    if (trace && trace.length) {

        msgStack.push('TRACE:');

        trace.forEach(function(t) {

            msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));

        });

    }

    // uncomment to log into the console

    // console.error(msgStack.join('\n'));

};

// 打开页面

page.open(url, function (status) {

//  console.log('spider--url:'+url);

    if (status !== 'success') {

        setTimeout(phantom.exit(), 1500);

    } else {

        // 当改页面的初始html返回成功后,开启定时器

        // 当到达最大时间(默认5秒)的时候,截取那一时刻渲染出来的html

        maxWaitTimer = setTimeout(function(){

            capture(2);

        }, maxWait);

    }

});


        3. 以此为基础 在命令行里执行 phantomjs

        phantomjs   spider.js  https://www.baidu.com

我们会发现不会返回内容,因为 访问https失败 需要增加配置 修改为

        phantomjs --ignore-ssl-errors=true   spider.js  https://www.baidu.com

我们就能看到返回的内容啦

但是我们的目的是通过蜘蛛访问到地址后获得返回内容,因此我们还需要以下操作


        4 创建服务向外暴露phantomjs返回内容

接下来我们就需要用到nodejs啦,我们需要用到express创建一个服务,然后把phantomjs,,放在nodejs的子进程后,监听子进程退出事件,获得phantomjs的返回内容,然后返回给浏览器。

具体实现如下



// server.js

// ExpressJS调用方式

var express = require('express');

// var phantomjs = require('phantom');

var app = express();

var path = process.cwd();

// 引入NodeJS的子进程模块

var child_process = require('child_process');

app.get('*', function(req, res){

    // 部署到服务器的完整URL

    var url = req.protocol + '://'+ req.hostname + req.originalUrl;

    // var url = 'https://test.zgzjzj.com/font/newtest/#/index';

    console.log('server--url:'+url);

    console.log('server--req:'+req.ip);

    try {

        console.log('server--req:'+JSON.stringify(req));

    } catch (error) {


    }

    // 测试的url

    // var url = 'https://www.baidu.com'


    // 预渲染后的页面字符串容器

    var content = '';

    // 开启一个phantomjs子进程

    var phantom = child_process.spawn('phantomjs', ['--ignore-ssl-errors=true','--load-images=false','--local-storage-path=/usr/local/storage',path + '/spider.js', url]);

console.log(phantom);

    // 设置stdout字符编码

    phantom.stdout.setEncoding('utf8');

    // 监听phantomjs的stdout,并拼接起来

    phantom.stdout.on('data', function(data){

        content += data.toString();

    });

    // 监听子进程退出事件

    phantom.on('exit', function(code){

    console.log("content是:")

    console.log(content)

        switch (code){

            case 1:

                console.log('加载失败');

                res.send('加载失败');

                break;

            case 2:

                console.log('加载超时: '+ url);

                res.send(content);

                break;

            default:

                console.log('加载页面: '+ url);

                res.send(content);

                break;

        }

    });

});

app.listen(8081, function () {

  console.log('Spider app listening on port 8081!');

  console.log(path + '/spider.js')

});

现在我们就可以通过访问服务器IP地址实现 phantomjs的访问了!



        5. 到此为止我们已经完成了一大半内容,现在的问题是,我们怎么才能通过访问实际项目地址实现获取渲染后的页面内容

        此处就需要使用到nginx了,以下需要有nginx的基础

        我们在前端项目服务器nginx配置文件里 增加如下代码:


http {...............

    upstream spider_server {

       server 3x.9x.1xx.2xx:8081;//安装phantomjs的服务器

    } ...........

}

location /{

......

    if ($http_user_agent ~* "Baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|bingbot|Sosospider|Sogou Pic Spider|Googlebot|360Spider"){

       proxy_pass  http://spider_server;

    }

......

}




        重启nginx后 就可以啦

        这里可以用百度模拟抓取测试一下

        也可以用第三方模拟抓取测试一下“http://www.cjzzc.com/crawl.html”

                        可以用一下网址进行测试

        顺便给我司网站做一个外链 专技天下网  甘肃专技 北京思想天下 北京思想天下 甘肃专技 甘肃省地质矿产勘查开发局继续教育培训平台


6.接下来对项目进行优化

        (1)尽量把hash模式改为history模式。

        (2)如果可以分模块部署vue项目那就再好不过了!

        (3)对于项目内的新闻模块或产品模块可以用一些<a href="***" title="******************"></a>, 减少路由跳转!

          (4)  可能的话 发发外链!多在百度站长提交一些网址!

        (5)对项目各个页面进行TDK的设置,可以从后台增加 ,也可从前台直接取接口中的新闻标题等。


说个重要的东西,

!!!!!

phantom.js不支持es6的语法,所以在index.html或者静态引用的资源里一定要避免使用es6的语法!!!!!!!!!




友情链接

甘肃档案专业继续教育培训平台 https://gsda.zgzjzj.com

新疆兵团第八师教育局专业技术人员培训平台 https://btbsjy.zgzjzj.com

甘肃兰州新区专业技术人员继续教育培训平台 https://lzxq.zgzjzj.com

甘肃白龙江林业保护中心专业技术人员继续教育培训平台 https://bljly.zgzjzj.com

甘肃武威市专业技术人员继续教育培训平台 https://wws.zgzjzj.com

甘肃甘南藏族自治州专业技术人员继续教育培训平台 https://gnz.zgzjzj.com

甘肃金昌市专业技术人员继续教育培训平台 https://jcs.zgzjzj.com

甘肃省专业技术人员继续教育培训平台 https://gs.zgzjzj.com

甘肃张掖市专业技术人员继续教育培训平台 https://zhangye.zgzjzj.com

甘肃省专业技术人员继续教育培训平台 https://gs.zgzjzj.com

甘肃省体育局继续教育培训平台 https://gsstyj.zgzjzj.com

盐城工学院 https://yancheng.zgzjzj.com

安徽省档案专业技术人员继续教育平台 https://ahda.zgzjzj.com

甘肃省自然资源行业专业技术人员继续教育平台 https://gszrzy.zgzjzj.com

甘肃省会计专业技术人员继续教育培训平台 https://gskuaiji.zgzjzj.com

兰州兰石集团专业技术人员继续教育培训平台 https://lzlsjt.zgzjzj.com

广西财政厅会计人员网络继续教育培训平台 https://gxczj.zgzjzj.com

安徽省应急管理(安全生产)培训平台 https://ahyjpx.zgzjzj.com

四川矿产机电技师学院培训平台 https://sckcjspx.zgzjzj.com

兰州市人事培训考试局 https://lzksj.zgzjzj.com

广西中小企业联合会培训中心 https://gxsme.zgzjzj.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容