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

如何为Express.js设置根路由?静态资源与Bot过滤冲突求助

解决Express根路由跳过Bot过滤的问题

问题描述

我是Express.js新手,这个问题已经卡了4小时。我的Express服务器需要返回React构建产物,用useragent库实现仅非Bot用户能访问应用。目前访问http://localhost:8080/connect能正常按规则返回页面,但访问根路由http://localhost:8080/时会跳过Bot过滤直接返回页面。我知道问题出在app.use(express.static("public/dist"));,但移除它会导致部分资源加载失败,加根路由中间件又会阻塞整个应用,求解决方法。

原代码:

const express = require('express');
const {PORT, CLIENT_URL} = require('./constants');
const app = express();
const cookieParser = require('cookie-parser');
const passport = require('passport');
const cors = require('cors');
const useragent = require('express-useragent');
const path = require('path'); // 原代码遗漏该模块,需补充

app.use(express.static("public/dist"));
app.use(useragent.express());
app.use(express.json());
app.use(cookieParser());
app.use(cors({ origin: CLIENT_URL, credentials:true }))

app.use('/api',authRoutes); // 我的API路由

app.get("/connect",async (req,res)=> {
    console.log(req.useragent.isBot)
    if (req.useragent.isBot == false){
    try{
        res.sendFile(path.resolve(__dirname,"..","public","dist","index.html"));
    } catch(err){
        res.json({
            "Error": "ERROR",
            "status": err
        })
    }
} else {
    try {
        res.status(403)     
    } catch (error) {
        res.status(403);   
    }
 }
})

const appStart = () => {
    try {
        app.listen(PORT , () => {
            console.log(`The app is running at http://localhost:${PORT}`);
        });
    } catch (error){
        console.log(`Error: ${error.message}`);
    }
};

appStart();

文件夹结构:

project
├── public
│   └── dist  # React构建产物目录
└── src
    └── index.js

解决方案

核心思路

问题根源是express.static中间件会优先处理静态文件请求,且默认不会经过后续路由校验。需要:

  • 提前解析用户代理信息,确保所有请求能获取req.useragent
  • 给静态资源请求添加Bot过滤逻辑,仅拦截根路径和index.html的Bot请求,允许其他静态资源正常加载
  • 保留根路由的校验逻辑,保证单页应用路由刷新正常

修改后的完整代码

const express = require('express');
const {PORT, CLIENT_URL} = require('./constants');
const app = express();
const cookieParser = require('cookie-parser');
const passport = require('passport');
const cors = require('cors');
const useragent = require('express-useragent');
const path = require('path');

// 1. 优先解析用户代理,确保所有请求能拿到useragent信息
app.use(useragent.express());
app.use(express.json());
app.use(cookieParser());
app.use(cors({ origin: CLIENT_URL, credentials:true }))

// 2. 给静态资源添加Bot过滤中间件
app.use((req, res, next) => {
    // 仅拦截根路径或index.html的Bot请求,其他静态资源(js/css/img等)正常放行
    const isRootOrIndex = req.path === '/' || req.path === '/index.html';
    if (isRootOrIndex && req.useragent.isBot) {
        return res.status(403).send("Forbidden");
    }
    next();
}, express.static("public/dist"));

app.use('/api',authRoutes); // API路由

// 3. 统一处理根路由和connect路由的Bot校验
app.get(["/", "/connect"], async (req,res)=> {
    console.log(req.useragent.isBot);
    if (req.useragent.isBot === false){
        try{
            res.sendFile(path.resolve(__dirname,"..","public","dist","index.html"));
        } catch(err){
            res.status(500).json({
                "Error": "Failed to load page",
                "status": err.message
            })
        }
    } else {
        res.status(403).send("Forbidden");
    }
})

const appStart = () => {
    try {
        app.listen(PORT , () => {
            console.log(`The app is running at http://localhost:${PORT}`);
        });
    } catch (error){
        console.log(`Error: ${error.message}`);
    }
};

appStart();

关键修改说明

  • 调整中间件顺序:把useragent.express()移到最前面,确保所有请求(包括静态资源请求)都能解析用户代理信息
  • 静态资源过滤逻辑:添加前置中间件,只拦截根路径和index.html的Bot请求,避免影响其他静态资源加载
  • 合并路由处理:把根路由和/connect路由的校验逻辑合并,减少重复代码
  • 补充响应内容:原代码仅设置403状态码未返回响应内容,补充send("Forbidden")确保客户端收到明确提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:08:13