启用connect-history-api-fallback后,Express图片接口返回304无法获取图片
解决connect-history-api-fallback导致/avatar图片接口返回304的问题
我之前也碰到过一模一样的坑,这问题的根源在于connect-history-api-fallback的默认行为——它会把所有非静态文件的GET请求都重写为/index.html,直接导致你的/avatar动态接口被拦截,浏览器拿到的其实是前端首页文件,再加上缓存机制就返回了304状态码。
问题拆解
看你的代码执行顺序:如果启用app.use(history()),请求会先经过connect-history-api-fallback中间件,它不知道/avatar是后端接口,只会判定这是一个不存在的静态资源路径,直接把请求重定向到/index.html,你的接口逻辑根本没机会执行。
解决方案:配置路由白名单
给connect-history-api-fallback添加rewrites规则,让它跳过/avatar路径的重写,直接把请求交给后面的路由处理:
修改你的中间件配置代码:
const history = require('connect-history-api-fallback') // 配置rewrites规则,排除/avatar接口 app.use(history({ rewrites: [ { from: /^\/avatar.*$/, to: function(context) { return context.parsedUrl.pathname } } ] }))
另外要注意保持中间件顺序:connect-history-api-fallback必须放在express.static之前,这样才能先处理路由重写,再响应静态资源请求——你的代码里的顺序是对的,继续保持就行。
额外优化:简化图片流返回逻辑
顺便提一句,你手动收集流数据再拼接返回的写法有点冗余,Express支持直接把文件流管道到响应对象,代码可以简化成这样:
router.get('/avatar', async (req, res, next) => { const id = req.query.file_id const url = await FileModel.getFilePath(id) res.set('content-type', 'image/jpg') // 直接把流pipe到res,自动处理end和错误捕获 fs.createReadStream(url).pipe(res).on('error', next) })
这样不仅代码更简洁,还能避免内存占用(不用把整张图片缓存到数组里),同时错误也能被Express的全局错误处理中间件捕获。
内容的提问来源于stack exchange,提问作者Yeachan
相关产品推荐
相关产品推荐

