多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Rendertron 服务器接入指南:在 Apache、Nginx 与 Express.js 中配置预渲染代理

Rendertron 服务器接入指南:在 Apache、Nginx 与 Express.js 中配置预渲染代理 后端【免费下载链接】rendertronA Headless Chrome rendering solution项目地址https://gitcode.com/gh_mirrors/re/rendertron点击查看免费下载Rendertron 是一个基于 Headless Chrome 的渲染服务能够为不执行 JavaScript 的搜索引擎爬虫和社交平台链接预览机器人提供预渲染后的静态 HTML。本文以仓库中的 docs/server-setup.md 及其下属三份服务器配置指南为主体系统讲解如何把已有的 Apache、Nginx、Express.js 服务器接入 Rendertron实现bot 请求走预渲染、普通用户请求直连的微分服务differential serving架构。读完本文你将掌握三种主流 Web 服务器的完整接入配置、bot 判定策略以及 rendertron-middleware 的底层实现原理与测试验证方法。为什么需要接入这一步Rendertron 本身是一个独立的 HTTP 服务服务端实现见 src/rendertron.ts它对外暴露GET /render/url端点接收一个目标页面 URL用 Puppeteer 启动的 Headless Chrome 打开并渲染页面等待页面加载完成后把序列化后的 HTML 返回给调用方同时保留原页面的 HTTP 状态码并附带x-renderer: rendertron响应头。也就是说Rendertron 并不接管你的站点入口流量。它消费的是完整 URL而非像传统代理那样直接面向客户端流量。因此在架构上你现有的 Web 服务器仍然处理全部请求只是需要按 User-Agent 把值得预渲染的请求重定向给 Rendertron再把渲染结果回传给爬虫。原文档 docs/server-setup.md 对这一步的定位非常明确Rendertron provides a web server that accepts request for rendering pages. Usually your web application already uses a web server and you need to configure your web server to redirect requests from the desired bots and crawlers to your Rendertron server.几乎所有常见 Web 服务器都能完成这一重定向只是具体步骤不同。仓库为三类最常用的服务器提供了专门指南Apache 接入指南nginx 接入指南Express.js 接入指南如果你有其他 Web 服务器的接入方案也可以参考 CONTRIBUTING.md 为官方文档补充内容。接入前必须了解的 Rendertron 服务端点在配置任何服务器之前先理解目标端点的形态能避免大量踩坑。以服务端路由实现src/rendertron.ts为准GET /render/url其中url是要渲染的目标页面完整地址含协议、主机名、端口、路径与查询参数。服务端会先通过restricted()方法做安全校验见 src/rendertron.ts只允许http/https协议、拒绝.internal结尾的内网主机名并可通过配置renderOnly白名单限制可渲染的域名非法请求返回403。另外两个与接入强相关的事实渲染预算硬上限为 10 秒服务端timeout默认10000毫秒src/config.ts 中写明默认值README 的 FAQ 也强调这是hard limit。你的应用页面必须在这段时间内完成渲染。支持mobile、timezoneId等查询参数/render/url?mobile可请求移动版渲染见 src/rendertron.ts。不过服务器接入时一般不需要显式追加这些参数按本文配置即可。因此服务器转发到 Rendertron 的最终请求形如http://your-rendertron-host/render/http://example.com:8080/foo?pagehome下面三节的配置本质都是在构造这样一个带完整目标 URL 的转发请求。使用 nginx 作为反向代理接入 Rendertronnginx 的接入思路是把 nginx 配置为反向代理检查$http_user_agent如果 User-Agent 看起来像 bot就把请求转发给 Rendertron否则直接交给你的 Web 应用。完整指南见 docs/server-setup/nginx.md。面向单一 bot 的配置如果只想把 User-Agent 中包含bot的请求发给 Rendertron可以直接在server块中使用if加rewriteserver { listen 80; server_name example.com; # ...other configuration... # only send requests from user agents containing the word bot to Rendertron if ($http_user_agent ~* bot) { rewrite ^(.*)$ /rendertron/$1; } location /rendertron/ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; # replace PUT-YOUR-RENDERTRON-URL-HERE with your rendertron server address below proxy_pass http://PUT-YOUR-RENDERTRON-URL-HERE/render/$scheme://$host:$server_port$request_uri; } }几个关键点值得展开~* bot是大小写不敏感的正则匹配所以googlebot、Bingbot都会被命中这也是它适合只要包含 bot 字样就预渲染这种粗粒度策略的原因。rewrite ^(.*)$ /rendertron/$1;把命中请求在内部重写到/rendertron/前缀下随后由location /rendertron/捕获。proxy_pass的目标不是简单的http://rendertron-host/而是带着/render/路径与一组 nginx 内置变量最终构造出 Rendertron 需要的完整目标 URL$scheme保留原始请求的协议http/https$host保留 Host 头中的主机名$server_port保留端口确保目标页面 URL 完整可回访$request_uri保留原始请求的完整 URI含查询字符串。当proxy_pass带有 URI 部分/render/...时nginx 会用 location 匹配后剩余的 URI 替换原 URI从而把/rendertron/foo变成/render/http://example.com:80/foo转发给 Rendertron。面向多个 bot User-Agent 的配置if中的单一正则难以维护多个 bot 列表。官方推荐在nginx.conf的http 上下文中使用map指令把 User-Agent 映射到一个自定义变量$is_bot# Creates $is_bot variable and match user agents map $http_user_agent $is_bot { default 0; ~*googlebot 1; ~*bingbot 1; # add more lines for other user agents here }然后在站点配置的server块中根据$is_bot决定是否转发server { listen 80; server_name example.com; # ...other configuration... # only send requests from user agents containing the word bot to Rendertron if ($is_bot 1) { rewrite ^(.*)$ /rendertron/$1; } location /rendertron/ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; # replace PUT-YOUR-RENDERTRON-URL-HERE with your rendertron server address below proxy_pass http://PUT-YOUR-RENDERTRON-URL-HERE/render/$scheme://$host:$server_port$request_uri; } }map中的~*googlebot同样是大小写不敏感的正则键default 0兜底所有未命中的 User-Agent。新增 bot 时只需在map里加一行比维护if正则清晰得多。要注意map只能出现在http上下文server块内无法定义。使用 Apache 接入 RendertronApache 的接入方式是基于 User-Agent 做条件 URL 重写既可以在.htaccess文件中也可以在VirtualHost或主配置文件中完成。完整指南见 docs/server-setup/apache.md。前置条件启用 rewrite 与 proxy 模块配置依赖mod_rewrite和mod_proxy_http两个模块。在 Debian / Ubuntu 上启用sudo a2enmod rewrite proxy_http sudo service apache2 restart基本配置把所有包含bot的请求发给 RendertronRewriteEngine On RewriteCond %{HTTP_USER_AGENT} bot # Replace the PUT-YOUR-RENDERTRON-URL-HERE with the URL of your Rendertron instance # Replace YOUR-WEBAPP-ROOT-URL with the base URL of your web application (e.g. example.com) RewriteRule ^(.*)$ https://PUT-YOUR-RENDERTRON-URL-HERE/render/https://YOUR-WEBAPP-ROOT-URL$1 [P,L]逐行拆解RewriteCond %{HTTP_USER_AGENT} bot条件匹配User-Agent 中包含bot即命中。RewriteRule ^(.*)$ ... [P,L][P]Proxy flag让 Apache 以反向代理身份转发请求而不是返回重定向这依赖mod_proxy_http[L]Last flag表示这是最后一条规则命中后不再处理后续规则。目标 URL 中把https://YOUR-WEBAPP-ROOT-URL替换为你的站点根地址如example.com再把捕获的$1追加到路径末尾最终得到https://rendertron/render/https://example.com原始路径。把多个 bot 的 User-Agent 发送给 Rendertron把多个 bot 名称用**管道符|**分隔放在同一个RewriteCond中即可RewriteEngine On RewriteCond %{HTTP_USER_AGENT} facebookexternalhit|linkedinbot|twitterbot # Replace the PUT-YOUR-RENDERTRON-URL-HERE with the URL of your Rendertron instance # Replace YOUR-WEBAPP-ROOT-URL with the base URL of your web application (e.g. example.com) RewriteRule ^(.*)$ https://PUT-YOUR-RENDERTRON-URL-HERE/render/https://YOUR-WEBAPP-ROOT-URL$1 [P,L]重要注意事项原文档明确警告这种RewriteCond的正则匹配是大小写敏感的——googlebot能命中而Googlebot不会命中。如果你的目标是 Googlebot 等官方 UA实际是Mozilla/5.0 ... Googlebot/2.1 ...大小写混合建议在 Apache 配置中用[NC]标志或在正则中显式覆盖大小写变体或者考虑改用下面介绍的 Express 中间件其默认匹配是i忽略大小写的。使用 Express.js 接入 Rendertron如果你使用 Express.js官方提供了现成的中间件包rendertron-middleware无需手写代理逻辑。完整指南见 docs/server-setup/expressjs.md中间件源码在 middleware/src/middleware.ts配置文档见 middleware/README.md。安装 rendertron-middleware在你的 Web 应用根目录执行npm install --save rendertron-middleware最小接入配置把中间件挂到 Express 应用的最前面并传入proxyUrlconst express require(express); const rendertron require(rendertron-middleware); const app express(); app.use( rendertron.makeMiddleware({ // replace this with the web address of your rendertron instance proxyUrl: http://PUT-YOUR-RENDERTRON-URL-HERE/render, }) ); app.use(express.static(files)); app.listen(8080);proxyUrl指向 Rendertron 服务的/render端点。中间件会检查每个请求的 User-Agent命中 bot 列表的请求被代理到 Rendertron其他请求调用next()继续走正常 Express 中间件链如上面的静态文件服务。注意makeMiddleware的实现会自动为proxyUrl补上末尾斜杠见 middleware/src/middleware.ts所以带不带/都能工作——这一点也被测试proxyUrl can have trailing slash覆盖middleware/src/test/middleware-test.ts。自定义与扩展 bot 列表中间件内置了一套预配置的 bot 列表定义于 middleware/src/middleware.ts包含Baiduspider、bingbot、Embedly、facebookexternalhit、LinkedInBot、outbrain、pinterest、quora link preview、rogerbot、showyoubot、Slackbot、TelegramBot、Twitterbot、vkShare、W3C_Validator、WhatsApp。这些覆盖了搜索引擎爬虫、社交平台链接预览和即时通讯链接抓取等典型场景。如果你需要接入其他 bot可以替换或扩展这份列表。替换默认列表只对 LinkedIn 和 Twitter 的 bot 预渲染// only use Rendertron for LinkedInBot and Twitterbot const myBotList [linkedinbot, twitterbot]; app.use( rendertron.makeMiddleware({ // replace the default bot list with your own: userAgentPattern: new RegExp(myBotList.join(|), i), // replace this with the web address of your rendertron instance proxyUrl: http://PUT-YOUR-RENDERTRON-URL-HERE/render, }) );扩展默认列表在原有 bot 基础上追加新 bot// add googlebot and yolobot to bot list const myBotList rendertron.botUserAgents.concat([googlebot, yolobot]); app.use( rendertron.makeMiddleware({ // use the extended bot list: userAgentPattern: new RegExp(myBotList.join(|), i), // replace this with the web address of your rendertron instance proxyUrl: http://PUT-YOUR-RENDERTRON-URL-HERE/render, }) );rendertron.botUserAgents正是源码中导出的那个数组两种写法最终都用join(|)构造正则并加i标志实现大小写不敏感匹配。makeMiddleware 的全部配置项除proxyUrl和userAgentPattern外中间件还支持以下配置依据 middleware/README.md 的配置表与 middleware/src/middleware.ts 的Options接口配置项默认值说明proxyUrl必填Rendertron 服务的基础地址通常以/render结尾缺失时会直接抛出Must set options.proxyUrl.错误userAgentPattern内置 bot 列表见上用于匹配 User-Agent 的正则表达式excludeUrlPattern常见静态资源扩展名集合用于按 URL 路径排除请求的正则默认排除.css、.js、.png、.jpg、.pdf、.zip等 40 余种静态资源扩展名完整列表见源码 middleware/src/middleware.ts避免对静态资源做无意义的预渲染injectShadyDomfalse为true时强制加载并启用 Web Components polyfillShady DOM会在渲染 URL 后追加?wc-inject-shadydomtrue适用于依赖 Shadow DOM 序列化的页面timeout11000毫秒代理请求到 Rendertron 的超时时间。注意这是中间件的超时不是 Rendertron 服务端本身的渲染预算服务端渲染上限为 10 秒timeout默认10000见 src/config.ts11 秒默认值正是为其留出的余量allowedForwardedHosts[]反向代理场景下允许从转发头中采信的 host 列表。只有当请求携带的转发 host 头值命中此数组时才用该 host 构造渲染 URL留空则完全禁用 host 转发出于安全考虑不信任任意转发头forwardedHostHeaderX-Forwarded-Host用于读取转发 host 的请求头名称仅在allowedForwardedHosts非空时生效中间件内部工作原理从源码 middleware/src/middleware.ts 可以看到完整的判定流程读取请求的user-agent头若缺失、不匹配userAgentPattern、或req.path命中excludeUrlPattern则调用next()放行走正常应用逻辑。构造目标页面 URL优先使用X-Forwarded-Host且必须命中allowedForwardedHosts白名单决定 host否则使用请求自身的host头组合出协议 host 原始URI的完整地址。拼接渲染 URLproxyUrl encodeURIComponent(incomingUrl)若injectShadyDom为true则追加?wc-inject-shadydomtrue。用request库向 Rendertron 发起请求并把响应管道化pipe(res)直接流式回传客户端若请求出错如超时、连接失败则打印错误日志并调用next()回落到正常服务。测试用例middleware/src/test/middleware-test.ts验证了这些行为无proxyUrl时抛错、bot 请求被代理、静态文件路径被排除/foo.png与/foo.png?params都直接放行、非 bot如Chrome放行、自定义userAgentPattern生效、代理错误状态与响应体透传如 500、超时后回落next()、以及X-Forwarded-Host只有命中白名单才被采信malicious.com会被忽略。接入后的通用建议与注意事项缓存与超时接入完成后如果页面渲染耗时接近服务端的 10 秒硬预算建议开启 Rendertron 的缓存cache可配置为memory、filesystem或 GCP 专用的datastore详见 docs/configure.md 与 src/config.ts并配合/invalidate/url端点清理缓存条目。同时可把中间件的timeout适当调高但不能解决服务端 10 秒预算问题避免慢页面直接 504。使用前提与项目状态需要说明的是当前仓库 README.md 开头明确声明该项目已deprecated弃用Google 官方已不再推荐将动态渲染作为常规 SEO 方案且 Rendertron 不会再被积极维护。这意味着本文的接入方式适用于仍在维护需要服务不执行 JavaScript 的爬虫的既有架构的开发者对于全新项目建议优先考虑 SSR服务端渲染或静态生成等方案。了解这一背景有助于你评估是否引入本文方案。延伸阅读docs/server-setup/nginx.mdnginx 接入完整指南docs/server-setup/apache.mdApache 接入完整指南docs/server-setup/expressjs.mdExpress.js 接入完整指南middleware/README.mdrendertron-middleware 配置说明middleware/src/middleware.ts中间件源码与内置 bot 列表middleware/src/test/middleware-test.ts中间件行为测试docs/api-reference.mdRendertron HTTP API 参考docs/configure.md服务端config.json配置项src/rendertron.tsRendertron 服务端实现赞分享后端【免费下载链接】rendertronA Headless Chrome rendering solution项目地址https://gitcode.com/gh_mirrors/re/rendertron点击查看免费下载相关推荐使用 Express.js 中间件为 Rendertron 接入动态预渲染安装、配置与源码级原理使用 Express.js 中间件为 Rendertron 接入动态预渲染安装、配置与源码级原理 Rendertron 是一个基于 Headless Chro后端rendertron-middleware 实战在 Express 应用中为搜索引擎与社交爬虫接入 Rendertron 预渲染rendertron middleware 实战在 Express 应用中为搜索引擎与社交爬虫接入 Rendertron 预渲染 本指南围绕仓库 middle后端Rendertron 使用指南基于 Headless Chrome 的 PWA 动态渲染与 SEO 预渲染服务Rendertron 使用指南基于 Headless Chrome 的 PWA 动态渲染与 SEO 预渲染服务 Rendertron 是 Google Chr后端上一篇es-toolkit/fp 的 join 函数用 pipe 管道将数组优雅拼接为字符串下一篇Foundry Forge Lint 规则详解named-struct-fields 与 Solidity 结构体命名字段初始化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表