test
This commit is contained in:
parent
c2a86a0d65
commit
642f057bbd
|
@ -0,0 +1,9 @@
|
|||
/node_modules
|
||||
/.env.local
|
||||
/.umirc.local.ts
|
||||
/config/config.local.ts
|
||||
/src/.umi
|
||||
/src/.umi-production
|
||||
/src/.umi-test
|
||||
/dist
|
||||
.swc
|
31
README.md
31
README.md
|
@ -1,2 +1,31 @@
|
|||
# PupTester
|
||||
# SeoServer
|
||||
|
||||
|
||||
#### node版本
|
||||
16及以上
|
||||
#### ng配置
|
||||
|
||||
```
|
||||
if ($http_user_agent ~* "googlebot|Mediapartners-Google|bingbot|google-structured-data-testing-tool|baiduspider|360Spider|Sogou Spider|Yahoo! Slurp China|^$")
|
||||
{#判断如果是网络爬虫,转发到node服务器下
|
||||
proxy_pass http://www.test.com:3000;
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
#### 依赖安装、运行
|
||||
|
||||
```bash
|
||||
// 依赖
|
||||
npm install
|
||||
npm install pm2 -g
|
||||
node node_modules/puppeteer/install.js // 安装无头浏览器,可能会缺依赖,可参见https://www.cnblogs.com/ilizhu/p/14504049.html
|
||||
|
||||
// 启动服务
|
||||
pm2 start index.js
|
||||
|
||||
```
|
||||
|
||||
|
||||
#### 配置
|
||||
config中修改redis地址端口、node服务端口、以及转发host
|
|
@ -0,0 +1,5 @@
|
|||
export const redis = 'redis://127.0.0.1:6379';
|
||||
export const host = 'https://www.gitlink.org.cn';
|
||||
// export const host = 'http://119.3.190.9:8000';
|
||||
|
||||
export const port = 3000;
|
|
@ -0,0 +1,32 @@
|
|||
import request from 'request';
|
||||
import express from 'express';
|
||||
import ssr from './ssr.js';
|
||||
import { port, host } from './config.js';
|
||||
|
||||
const app = express()
|
||||
|
||||
// app.get('/api/*', async (req, res) => {
|
||||
// request(`${host}${req.url}`).pipe(res);
|
||||
// });
|
||||
|
||||
// app.get('/react/build/*', async (req, res) => {
|
||||
// request(`${host}${req.url}`).pipe(res);
|
||||
// });
|
||||
|
||||
// app.get('/images/*', async (req, res) => {
|
||||
// request(`${host}${req.url}`).pipe(res);
|
||||
// });
|
||||
|
||||
// app.get('/system/lets/*', async (req, res) => {
|
||||
// request(`${host}${req.url}`).pipe(res);
|
||||
// });
|
||||
|
||||
app.get('*', async (req, res) => {
|
||||
const {html, ttRenderMs} = await ssr(`${host}${req.originalUrl}`);
|
||||
res.set('Server-Timing', `Prerender;dur=${ttRenderMs};desc="Headless render time (ms)"`);
|
||||
return res.status(200).send(html); // Serve prerendered page as response.
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`app listening on port ${port}`)
|
||||
})
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "seotest",
|
||||
"version": "1.0.0",
|
||||
"description": "seotest",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bluebird": "^3.7.2",
|
||||
"express": "^4.18.2",
|
||||
"puppeteer": "^21.2.0",
|
||||
"redis": "^4.6.8",
|
||||
"request": "^2.88.2"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { createClient } from 'redis';
|
||||
import { redis as url } from '../config.js';
|
||||
|
||||
const client = createClient({
|
||||
url: url,
|
||||
retry_strategy: function(options) {
|
||||
if (options.error && options.error.code === "ECONNREFUSED") {
|
||||
return new Error("The server refused the connection");
|
||||
}
|
||||
if (options.total_retry_time > 1000 * 60 * 60) {
|
||||
return new Error("Retry time exhausted");
|
||||
}
|
||||
if (options.attempt > 10) {
|
||||
return undefined;
|
||||
}
|
||||
return Math.min(options.attempt * 100, 3000);
|
||||
},
|
||||
});
|
||||
|
||||
client.on('error', err => console.log('Redis Client Error', err));
|
||||
|
||||
await client.connect();
|
||||
|
||||
export default client
|
|
@ -0,0 +1,42 @@
|
|||
import puppeteer from 'puppeteer';
|
||||
// import redisClient from './redis/index.js';
|
||||
|
||||
async function ssr(url) {
|
||||
// const REDIS_KEY = `ssr:${url}`;
|
||||
// const CACHE_TIME = 600; // 10 分钟缓存
|
||||
// const CACHE_HTML = await redisClient.get(REDIS_KEY);
|
||||
|
||||
// if (CACHE_HTML) {
|
||||
// return { html: CACHE_HTML, ttRenderMs: 0 };
|
||||
// }
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
const browser = await puppeteer.launch({
|
||||
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
||||
headless: 'new',
|
||||
ignoreHTTPSErrors: true,
|
||||
devtools: false,
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
try {
|
||||
// networkidle0 waits for the network to be idle (no requests for 500ms).
|
||||
await page.goto(url, {waitUntil: 'networkidle0'});
|
||||
await page.waitForSelector('#root', { timeout: 0 }); // ensure #posts exists in the DOM.
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
throw new Error('page.goto/waitForSelector timed out.');
|
||||
}
|
||||
|
||||
const html = await page.content(); // serialized HTML of page DOM.
|
||||
await browser.close();
|
||||
|
||||
const ttRenderMs = Date.now() - start;
|
||||
console.info(`Puppeteer rendered page: ${url} in: ${ttRenderMs}ms`);
|
||||
|
||||
// redisClient.set(REDIS_KEY, html, 'EX', CACHE_TIME); // cache rendered page.
|
||||
|
||||
return {html, ttRenderMs};
|
||||
}
|
||||
|
||||
export {ssr as default};
|
Loading…
Reference in New Issue