当应用 Vue,React 等开发前端页面时,如果采纳前端渲染模式,则对搜索引擎不太敌对。能够利用 chrome 将渲染好的页面内容输入给搜索引擎,以此达到动态化页面的目标。将其残缺封装到 Docker,更便于部署。
以下为 Dockerfile 及服务程序。
Dockerfile
FROM node:10EXPOSE 3000VOLUME /var/wwwWORKDIR /var/wwwADD package.js /var/wwwADD package.json /var/wwwENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1RUN apt-get update \ && apt-get install -y wget gnupg ca-certificates \ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ && echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list \ && apt-get update \ && apt-get install -y google-chrome-stable \ && npm installCMD ["npm", "start"]
package.js
const puppeteer = require('puppeteer');const path = require('path');const koa = require('koa');const app = new koa();const ref = "http://www.xxx.com"; // 理论网站网址let browser;app.use(async ctx=>{ if(!browser){ browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'], ignoreHTTPSErrors: true, // 疏忽 https 谬误 headless: true, // 不显示浏览器 devtools: false // 不关上控制台 }); } const page = await browser.newPage(); await page.goto(ref + ctx.request.url, { waitUntil: ['load', 'networkidle0'] // 加载实现, 无新申请, 则页面渲染结束 }); const html = await page.content(); page.close(); ctx.response.body = html;})app.listen(3000);
package.json
{ "name": "spa-seo", "author": "Hongs", "license": "MIT", "version": "1.0.0", "keywords": ["SPA","SEO"], "description": "SPA SEO", "main": "package.js", "scripts": { "start": "node package.js" }, "dependencies": { "koa": "^2.7.0", "mime": "^2.4.5", "mkdirp": "^1.0.4", "rimraf": "^3.0.2", "hotnode": "0.0.8", "puppeteer": "^1.18.1", "extract-zip": "^2.0.0" }}
构建及执行:
docker build -t xxx/seo .docker run -m 256m -p 3000:3000 --read-only --name xxx/seo xxx/seo
nginx server 内配置:
location /path/to/spa { if ($http_user_agent ~* "Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|HttpClient|MJ12bot|EasouSpider|Ezooms|heritrix|qihoobot|^$") { proxy_pass http://127.0.0.1:3000; break; } # ...}