You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular Universal中根据请求来源切换服务处理逻辑?

解决方案:通过User-Agent区分请求来源,实现CSR/SSR分流

完全可以通过在server.ts中识别请求的User-Agent,实现浏览器请求返回静态CSR文件、爬虫请求走SSR渲染的逻辑,完美解决你遇到的兼容问题和SEO需求。

核心思路

通过解析请求头中的User-Agent字段,判断请求是否来自搜索引擎或社交平台爬虫:

  • 浏览器请求:直接返回Angular构建后的静态index.html(CSR模式),保留原有应用的所有功能和第三方库兼容性
  • 爬虫请求:触发Angular Universal的SSR渲染,返回包含动态meta标签的页面,满足SEO需求

具体实现步骤

1. 定义爬虫User-Agent列表

先整理主流搜索引擎、社交平台的爬虫标识,覆盖Google、Twitter、Facebook、WhatsApp等目标平台:

// 主流爬虫的User-Agent关键词列表
const CRAWLER_UAS = [
  'googlebot',
  'bingbot',
  'twitterbot',
  'facebookexternalhit',
  'whatsapp',
  'linkedinbot',
  'pinterestbot',
  'slackbot',
  'yandexbot',
  'baiduspider'
];

// 判断请求是否来自爬虫的工具函数
function isCrawler(userAgent: string | undefined): boolean {
  if (!userAgent) return false;
  const lowerUA = userAgent.toLowerCase();
  return CRAWLER_UAS.some(crawlerUA => lowerUA.includes(crawlerUA));
}

2. 修改server.ts的路由逻辑

在原有Universal服务的基础上,添加分流判断逻辑:

import { join } from 'path';
import * as express from 'express';
import { renderModule } from '@angular/platform-server';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { readFileSync } from 'fs';

const DIST_FOLDER = join(process.cwd(), 'dist/your-app-name');
const indexHtml = readFileSync(join(DIST_FOLDER, 'browser', 'index.html'), 'utf-8');
const app = express();

// 先处理静态资源(JS、CSS、图片等)
app.use(express.static(join(DIST_FOLDER, 'browser'), {
  maxAge: '1y'
}));

// 处理所有页面请求
app.get('*', async (req, res) => {
  const userAgent = req.headers['user-agent'];
  
  if (isCrawler(userAgent)) {
    // 爬虫请求:触发SSR渲染
    const html = await renderModule(AppServerModule, {
      document: indexHtml,
      url: req.originalUrl,
      extraProviders: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }]
    });
    res.send(html);
  } else {
    // 浏览器请求:直接返回静态CSR文件
    res.sendFile(join(DIST_FOLDER, 'browser', 'index.html'));
  }
});

app.listen(process.env.PORT || 4000, () => {
  console.log(`Server is running on port ${process.env.PORT || 4000}`);
});

3. 测试验证

  • 浏览器访问:直接打开应用,确认原有功能、第三方库、localStorage/window相关代码正常工作
  • 模拟爬虫请求:用curl命令模拟爬虫UA,验证返回的是SSR渲染后的页面:
curl -A "Googlebot/2.1 (+http://www.google.com/bot.html)" http://your-domain.com/your-dynamic-page

查看返回的HTML源码,确认动态meta标签已正确渲染。

注意事项

  • 后续如果需要支持新的爬虫,只需在CRAWLER_UAS列表中添加对应的UA关键词即可
  • 确保静态文件路径DIST_FOLDER与Angular构建后的输出目录一致
  • 部分爬虫可能会使用多个UA标识,可根据实际需求扩展列表
  • 这种方案完全规避了第三方库的SSR兼容问题,同时满足SEO的核心需求

内容的提问来源于stack exchange,提问作者Osama El-Masri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:20:50