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

如何避免Express.js认证中间件捕获HTTP OPTIONS请求

解决Express认证中间件拦截OPTIONS预请求的问题

我之前也碰到过一模一样的坑!浏览器发送的OPTIONS预请求(也就是CORS预检请求)本来就不会带Authorization头,所以咱们的认证中间件得先把这类请求直接放行,别拦着。下面给你两个实用的解决办法:

方法一:在自定义认证中间件里跳过OPTIONS请求

最简单直接的方式,就是在你的认证中间件开头加个判断——如果请求方法是OPTIONS,就直接调用next()让它通过:

// 你的自定义认证中间件
const authMiddleware = (req, res, next) => {
  // 先放行OPTIONS预请求
  if (req.method === 'OPTIONS') {
    return next();
  }

  // 下面是你原本的认证逻辑
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ message: 'Unauthorized' });
  }

  const token = authHeader.split(' ')[1];
  // 这里写你的token验证逻辑,比如用jsonwebtoken的verify方法
  // ...
  next();
};

// 把中间件挂载到需要权限验证的路由上
app.use('/api/protected', authMiddleware);

方法二:用cors包自动处理预检请求

如果你的项目还没配置跨域,推荐直接用官方的cors npm包,它会自动帮你处理OPTIONS预请求,不用自己写判断逻辑,省心很多:

首先安装依赖:

npm install cors

然后在Express应用里配置:

const cors = require('cors');

// 配置CORS,允许你的Angular应用域名,同时放行Authorization头
app.use(cors({
  origin: 'http://your-angular-app-domain.com', // 替换成你的Angular实际域名
  allowedHeaders: ['Authorization', 'Content-Type'],
  credentials: true // 如果需要携带cookie就开启,不需要可以删掉
}));

// 之后再挂载你的认证中间件
app.use('/api/protected', authMiddleware);

这个方法的优势在于,cors包会自动响应OPTIONS请求并返回正确的CORS头,而且不会触发你的认证中间件,从根源上避免了拦截问题。

补充:为什么会出现这个问题?

浏览器的同源策略规定,当前端发送跨域复杂请求(比如带自定义头的GET请求)时,会先发送一个OPTIONS预请求,用来询问服务器是否允许这个跨域请求。这个预请求不会携带任何自定义头(包括Authorization),所以如果咱们的认证中间件没做特殊处理,就会把它当成未授权请求拦截掉,导致实际的GET请求根本没机会发送。

另外你的Angular请求代码是没问题的,它确实在实际GET请求里带了Authorization头,只要解决了OPTIONS的拦截问题,就能正常请求接口啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:58:45