Angular添加Authorization请求头后发送OPTIONS预检请求是否正常?
问题描述
我在Angular 12中通过HTTP拦截器添加Authorization请求头后,Firefox v.119.0b6开始发送OPTIONS预检请求,从预检请求的Access-Control-Request-Headers: authorization头可以看出,浏览器在检查这个头是否被允许。
添加Authorization头的代码如下:
req = req.clone({ headers: req.headers.set('Authorization', `Bearer ${token}`) })
我的疑问是:这种情况是否正常?我猜测是不是小写的'a'让浏览器把它当成了自定义头?或者是否需要做什么修改?目前这个请求在Firefox里能正常发送,但Chrome/Edge在localhost环境下无法正常工作,而且我没找到其他人遇到过这个现象。
另外我对比了我们另一款同样发送Authorization头的产品(AngularJS + ASP.NET),它不会发送OPTIONS预检请求;在开启--disable-web-security的Chrome中测试,也没有预检请求。
解答
1. 现象是否正常?
正常,但和头的大小写无关——HTTP请求头是大小写不敏感的,浏览器和服务器都会统一解析,小写的authorization不会被识别为自定义头。
触发OPTIONS预检的核心原因是你的请求属于非简单请求,即使带有Authorization头,只要满足以下任一条件就会触发预检:
- 请求方法不是GET、HEAD、POST中的一种
- POST请求的
Content-Type不是application/x-www-form-urlencoded、multipart/form-data、text/plain三者之一 - 请求中包含了除简单头(如Accept、Accept-Language、Content-Language、Content-Type)之外的其他头(不过
Authorization本身属于允许在简单请求中携带的头,所以大概率是前两个条件导致)
Firefox测试版出现预检而其他场景没出现,可能是浏览器版本的临时行为差异,或是不同请求的自身属性不同(比如你当前Angular 12的请求方法/Content-Type和AngularJS产品的请求不一样)。
2. 为什么其他场景无预检?
- 那款AngularJS产品的请求是简单请求:比如用了GET/POST,且
Content-Type符合简单请求要求,这种情况下即使携带Authorization头也不会触发预检。 - 开启
--disable-web-security的Chrome会跳过CORS校验,自然不会发送预检请求。
3. 是否需要修改?
如果后端已经正确处理了OPTIONS预检请求(返回包含Access-Control-Allow-Headers: authorization、Access-Control-Allow-Methods等必要头的响应),且业务请求能正常完成,完全不需要修改。
如果后端未处理预检请求,导致请求失败,那需要在后端配置CORS规则:
- 允许OPTIONS方法
- 配置
Access-Control-Allow-Headers包含authorization - 确保
Access-Control-Allow-Origin设置正确
内容的提问来源于stack exchange,提问作者banapaya

