如何让Express路由匹配目录内任意PDF文件并执行回调?
解决Express中访问静态PDF文件时自定义路由回调不执行的问题
这个问题的核心原因是Express中间件的执行顺序:如果你已经用express.static托管了Buyer_templates目录,那么静态文件中间件会优先于你定义的app.get路由处理请求。当请求匹配到目录中存在的PDF文件时,静态中间件会直接返回文件内容,不会继续触发后续的自定义路由回调——这就是为什么你访问不存在的路径(比如/Buyer_templates/blahblahblah)时路由生效,而访问真实PDF文件时没反应。
下面是两种可行的解决方案:
方案一:调整路由与静态中间件的顺序,手动处理文件返回
把你的自定义路由注册在express.static之前,这样所有/Buyer_templates/*的请求都会先经过你的授权逻辑,验证通过后再手动返回对应文件:
const express = require('express'); const app = express(); const path = require('path'); // 1. 先注册自定义路由,优先处理所有Buyer_templates下的请求 app.get('/Buyer_templates/*', (req, res) => { // 第一步:执行你的授权验证逻辑 // 示例:假设你通过session或token判断用户是否授权 const isAuthorized = req.session?.user?.isAuthorized; // 替换成你的实际验证逻辑 if (!isAuthorized) { return res.redirect('/'); // 无权限则跳转 } // 第二步:验证通过,返回对应的PDF文件 const targetFile = req.params[0]; // 获取*匹配到的文件名,比如"file.pdf" const fullPath = path.join(__dirname, 'Buyer_templates', targetFile); res.sendFile(fullPath, (err) => { if (err) { res.status(404).send('Requested file not found'); } }); }); // 2. 再注册静态中间件(此时它不会处理Buyer_templates下的请求,因为路由已经拦截了) app.use(express.static('public')); // 假设你的其他静态文件放在public目录 app.listen(3000, () => { console.log('Server running on http://localhost:3000'); });
方案二:移除静态托管,完全通过路由控制访问
如果你不需要Buyer_templates目录被公开访问,直接去掉该目录的express.static配置,完全通过自定义路由处理所有请求——这样所有访问/Buyer_templates/*的请求都会触发你的回调,你可以自由控制授权和文件返回逻辑。
为什么之前的路由规则无效?
你尝试的/Buyer_templates/*.*、/Buyer_templates/(.*)这些路径规则本身是没问题的,但问题出在执行顺序:静态中间件先一步处理了存在的文件请求,你的路由根本没机会执行。只有当请求的文件不存在时,静态中间件才会把请求交给后续的路由处理,这就是为什么访问不存在的路径时你的回调能触发。
内容的提问来源于stack exchange,提问作者Martin Harris
相关产品推荐
相关产品推荐

