一、為什么 Vue 需要專門做 SEO
? ? ??Vue 默認是客戶端渲染 SPA,首屏 HTML 幾乎為空,爬蟲抓取不到內容;即使 Googlebot 能執行 JS,也存在“渲染預算”與加載延遲問題
二、技術落地 4 條路線
場景 | 技術選型 | 實現要點 | 適用 |
內容更新頻繁、SEO 高要求 | Nuxt3 SSR | npx nuxi@latest init my-seo-app ;useHead() ?設置 title/meta;useAsyncData() | 企業官網、電商 |
內容相對靜態 | Nuxt3 SSG | nuxt generate ?一鍵生成純靜態文件;部署到 CDN 即可 | 博客、文檔 |
只想給幾個關鍵路由做 SEO | 預渲染 | npm i prerender-spa-plugin -D ;在?vue.config.js ?中配置需要預渲染的路由即可 缺點:CSS和JS不可用 | 活動頁、落地頁 |
已開發完的 SPA 不想重構 | 動態渲染 | 用 Puppeteer/Rendertron 針對爬蟲返回靜態 HTML;配合 Nginx UA 判斷(最好選擇:Puppeteer) | 舊項目應急 |
三、用 Puppeteer針對爬蟲返回靜態 HTML;配合 Nginx UA 判斷
? 描述:? 真人訪問 → 正常返回 SPA 的 index.html
? ? ? ? ? ? ? 爬蟲訪問 → 由 Rendertron(或 Puppeteer)渲染成靜態 HTML 后返回
3.1?Puppeteer 渲染服務(Node)
# 安裝
npm i express puppeteer
server.js
const express = require('express');
const puppeteer = require('puppeteer');const app = express();
let browser;(async () => {browser = await puppeteer.launch({headless: 'new',args: ['--no-sandbox', '--disable-setuid-sandbox']});
})();app.get('/render', async (req, res) => {const { url } = req.query;if (!url) return res.status(400).send('url required');const page = await browser.newPage();await page.setUserAgent('Mozilla/5.0 (compatible; PuppeteerRender/1.0)');await page.goto(url, { waitUntil: 'networkidle2' });const html = await page.content();await page.close();res.set('Cache-Control', 'public, max-age=300'); // 5 分鐘 CDN 緩存res.send(html);
});app.listen(3001, () => console.log('Puppeteer render service on 3001'));
?運行:
node server.js
測試:瀏覽器:?http://localhost:3001/render?url=https://www.baidu.com(自己網址)
?或者 :curl?http://localhost:3001/render?url=https://www.baidu.com(自己網址)
查看內容和瀏覽器渲染一樣即可
3.2 nginx配置
map $http_user_agent $is_bot {default 0;~*Googlebot 1;~*Baiduspider 1;~*bingbot 1;~*Slurp 1;~*DuckDuckBot 1;
}
server
{listen 80;listen 443 ssl http2 ;server_name baidu.com;index index.html index.htm default.htm default.html;root /www/wwwroot/www_t.baidu.com;try_files $uri $uri/ /index.html;#CERT-APPLY-CHECK--START# 用于SSL證書申請時的文件驗證相關配置 -- 請勿刪除并保持這段設置在優先級高的位置include /www/server/panel/vhost/nginx/well-known/tw.yougo.vip.conf;#CERT-APPLY-CHECK--END#REWRITE-ENDlocation / {proxy_set_header X-Original-Host $host;proxy_set_header X-Original-Request-URI $request_uri;proxy_set_header User-Agent $http_user_agent;# 1. 如果是爬蟲 → 代理到 Puppeteerif ($is_bot) {proxy_pass http://127.0.0.1:3001/render?url=$scheme://$host$request_uri;# 傳遞必要頭部break;}# 2. 真實用戶 → SPAtry_files $uri $uri/ /index.html;}#禁止訪問的文件或目錄location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md){return 404;}#一鍵申請SSL證書驗證目錄相關設置location ~ \.well-known{allow all;}#禁止在證書驗證目錄放入敏感文件if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {return 403;}location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)${expires 30d;error_log /dev/null;access_log /dev/null;}location ~ .*\\.(js|css)?${expires 12h;error_log /dev/null;access_log /dev/null;}access_log /www/wwwlogs/tw.yougo.vip.log;error_log /www/wwwlogs/tw.yougo.vip.error.log;
}
主要的配置點是:
map $http_user_agent $is_bot {default 0;~*Googlebot 1;~*Baiduspider 1;~*bingbot 1;~*Slurp 1;~*DuckDuckBot 1;
}location / {proxy_set_header X-Original-Host $host;proxy_set_header X-Original-Request-URI $request_uri;proxy_set_header User-Agent $http_user_agent;# 1. 如果是爬蟲 → 代理到 Puppeteerif ($is_bot) {#proxy_pass http://localhost:3001/render?url=$scheme://$host$request_uri;proxy_pass http://127.0.0.1:3001/render?url=$scheme://$host$request_uri;# 傳遞必要頭部break;}# 2. 真實用戶 → SPAtry_files $uri $uri/ /index.html;}
配置即可(注意配置時,不要使用localhost 這樣nginx解析會出錯)
測試:使用POSTMan測試
主要是User-Agent? ?Mozilla/5.0 (compatible; Baiduspider/2.0)
這樣就可以模擬百度爬蟲,進行訪問