Angular 8 HttpClient Get请求转为Options请求的解决方法咨询
解决Angular请求被转为OPTIONS的CORS问题
这是典型的CORS预飞行请求场景,我来一步步帮你理清问题和解决方案:
为什么你的GET请求变成了OPTIONS?
浏览器的CORS安全机制规定:当发送的是「非简单请求」时,会先自动发送一个OPTIONS预飞行请求,用来询问服务器是否允许跨域的实际请求(也就是你要发的GET)。你的请求刚好满足非简单请求的条件:
- Content-Type是
application/vnd.sas.datamgmt.jobflow.metadata+json,不属于application/x-www-form-urlencoded、multipart/form-data、text/plain这三种简单类型 - 带有自定义的Authorization请求头
所以浏览器先发起OPTIONS请求确认权限,这不是你的代码直接触发的,是浏览器的自动安全校验步骤。
第一步:修正客户端代码里的错误
你的请求头配置有几个明显问题,先调整:
1. 修复Authorization头格式
你代码里'Basic' + btoa(...)少了Basic后面的空格,这会导致认证直接失败,正确写法是:
'Authorization': 'Basic ' + btoa('username:password')
2. 移除多余的请求头
Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Allow-Methods这些是服务器返回的响应头,不是客户端请求头,你加在请求里完全没用,反而可能干扰预飞行判断,直接删掉这些行:
// 删掉这些无用的配置: // httpOptions.headers.set('username', 'password'); // httpOptions.headers.append('Access-Control-Allow-Origin', '*'); // httpOptions.headers.append('Access-Control-Allow-Credentials', 'true'); // httpOptions.headers.append('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
3. (可选)添加凭证配置
如果你的请求需要携带Cookie等凭证,在httpOptions里加上withCredentials: true:
修正后的完整客户端代码:
const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/vnd.sas.datamgmt.jobflow.metadata+json; charset=utf-8', 'Authorization': 'Basic ' + btoa('username:password') // 注意Basic后面的空格! }), withCredentials: true // 只有当服务器允许凭证时才加 }; this.typesOfDBs = this.http.get<Info[]>(this.ROOT_URL, httpOptions);
第二步:配置Microsoft 2012服务器(IIS 8)的CORS规则
问题的核心是你的服务器没有正确响应OPTIONS预飞行请求,导致浏览器拒绝发送后续的GET请求。你需要在服务器的web.config里添加CORS配置:
打开站点的web.config,在<system.webServer>节点下添加以下配置:
<!-- 配置CORS响应头 --> <httpProtocol> <customHeaders> <!-- 替换成你的前端实际域名,比如http://localhost:4200;如果不需要凭证可以用*,但带凭证时必须指定具体域名 --> <add name="Access-Control-Allow-Origin" value="http://your-frontend-domain" /> <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS" /> <!-- 必须包含你请求里用到的所有自定义头,比如Authorization和你的特殊Content-Type --> <add name="Access-Control-Allow-Headers" value="Authorization, Content-Type" /> <!-- 如果开启了withCredentials,这里要设为true --> <add name="Access-Control-Allow-Credentials" value="true" /> </customHeaders> </httpProtocol> <!-- 确保IIS不会拦截OPTIONS请求 --> <handlers> <remove name="OPTIONSVerbHandler" /> <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" responseBufferLimit="4194304" /> </handlers>
最后验证
配置好服务器后,重启IIS服务,再发起请求:
- 浏览器会先发送OPTIONS预飞行请求
- 服务器返回正确的CORS响应头后,浏览器会自动发送你的GET请求
这样就能解决OPTIONS请求拦截实际GET的问题了。
内容的提问来源于stack exchange,提问作者Geshe
相关产品推荐
相关产品推荐

