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

Node.js(Express)动态插入Meta标签报错:Uncaught SyntaxError: Unexpected token '<'

问题原因
  1. 缺少静态资源托管逻辑:你移除了原先的express.static中间件配置,仅处理了根路径/的请求返回修改后的index.html,但是网站依赖的JS、CSS、图片等静态资源的请求没有对应的处理逻辑,导致这类资源全部加载失败,页面无法正常渲染。
  2. 错误捕获逻辑无效:fs.readFile是异步回调风格的API,回调内抛出的错误无法被外层的try/catch捕获,就算读取文件出错也不会触发兜底的sendFile逻辑。
  3. 前端路由兼容缺失:如果你的React项目使用了BrowserRouter,除根路径外的其他前端路由(比如/detail、/profile)请求也不会被当前的app.get('/')匹配,会直接返回404。
解决办法

步骤1:恢复静态资源托管

将express.static中间件加回代码,且必须放在自定义的HTML处理路由之前,这样静态资源请求会优先被该中间件处理,只有非静态资源的请求才会走到后续的动态meta逻辑中:

// 优先托管build目录下的所有静态资源
app.use(express.static(path.resolve(__dirname, './client/build')));

步骤2:修复路由匹配和文件读取逻辑

把路由匹配规则改成通配符*覆盖所有前端路由,同时将fs.readFile改成同步读取或者Promise异步读取的写法,保证错误可以被正常捕获:

app.get('*', async (req, res) => {
  const pathToIndex = path.resolve(__dirname, './client/build', 'index.html');
  try {
    // 改用同步读文件,错误会被try/catch捕获
    const data = fs.readFileSync(pathToIndex, 'utf8');
    // 可根据req.path动态替换不同的meta内容
    const modifiedHtml = data.replace(/\$OG_TITLE/g, "ABC");
    res.send(modifiedHtml);
  } catch(err) {
    console.error('读取index.html失败:', err);
    res.sendFile(pathToIndex);
  }
});

如果偏好异步写法,可以改用fs.promises配合await:

const data = await fs.promises.readFile(pathToIndex, 'utf8');

可选优化:多路由动态meta适配

如果需要针对不同路由返回不同的meta标签,可以在替换逻辑中增加路径判断:

let ogTitle = "默认站点标题";
if (req.path === '/about') {
  ogTitle = "关于我们";
} else if (req.path.startsWith('/article/')) {
  // 可在此处查询数据库获取对应文章的专属标题
  ogTitle = "文章详情页";
}
const modifiedHtml = data.replace(/\$OG_TITLE/g, ogTitle);

内容的提问来源于stack exchange,提问作者dangtony98

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:45:03