Angular 9发起HTTP请求报跨域错误及401未授权问题求助
问题根因梳理
- CORS配置违规:响应头返回了两个
Access-Control-Allow-Origin值(http://localhost:4200和*),属于重复配置;同时你开启了Access-Control-Allow-Credentials: true,CORS规范明确禁止这种场景下使用*作为允许源,会直接导致跨域校验失败。
- CORS配置违规:响应头返回了两个
- Windows身份认证拦截预检请求:你的服务端启用了Windows身份认证(响应头
WWW-Authenticate: Negotiate/NTLM可验证),默认情况下IIS会拦截所有请求包括OPTIONS预检请求进行身份校验,但CORS预检请求不会携带身份凭据,直接就会返回401错误,导致正式请求根本不会发送。
- Windows身份认证拦截预检请求:你的服务端启用了Windows身份认证(响应头
- Angular请求未携带身份凭据:默认情况下Angular的HttpClient发跨域请求不会携带身份凭证(Cookie、Windows认证信息等),即使服务端要求Windows认证,也会因为没有凭据返回401。
- 本地代理配置错误:你的
proxy.conf.json中secure设为true,但目标地址是http协议,这个配置会导致代理校验SSL证书出错,代理转发异常。
- 本地代理配置错误:你的
可行解决方案
分两种场景,推荐优先用本地代理方案,避免CORS配置问题:
方案1:本地开发用代理(无需配置CORS,推荐)
本地开发用Angular代理转发的话,请求在浏览器侧是同域,不会触发跨域校验,直接关闭所有服务端CORS配置即可:
- 修改
proxy.conf.json配置:
{ "/api/*": { "target": "http://localhost:1234", "secure": false, "logLevel": "debug", "changeOrigin": true, "withCredentials": true } }
- 注释掉
global.asax中所有添加CORS响应头的代码,删除web.config中system.webServer/httpProtocol/customHeaders下的Access-Control-Allow-Origin配置项,避免多余的CORS头干扰。 - Angular发请求时统一添加
withCredentials: true配置,示例:
this.http.get('/api/Common/GetMy_List', { withCredentials: true })
方案2:直连API,修复CORS和认证配置
如果需要直接跨域调用API,按以下步骤修改:
- 修复CORS重复配置问题:删除
web.config中system.webServer/httpProtocol/customHeaders下的Access-Control-Allow-Origin配置项,仅保留global.asax中的CORS逻辑。 - 修正CORS允许源规则,禁止使用
*,修改global.asax中的源校验逻辑:
public void Application_BeginRequest(object sender, EventArgs e) { // 只允许明确的可信源,不要用* var allowedOrigins = new List<string> { "http://localhost:4200" }; string httpOrigin = Request.Params["HTTP_ORIGIN"]; if (allowedOrigins.Contains(httpOrigin)) { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Token"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true"); } if (Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.StatusCode = 200; var httpApplication = sender as HttpApplication; httpApplication.CompleteRequest(); } }
- 配置IIS允许OPTIONS请求匿名访问,避免Windows认证拦截预检请求,在
web.config中添加以下配置:
<location path="." inheritInChildApplications="false"> <system.web> <authorization> <allow verbs="OPTIONS" users="?"/> </authorization> </system.web> </location>
- Angular所有请求统一添加
withCredentials: true配置,和方案1第三步一致。
内容的提问来源于stack exchange,提问作者user1012506
相关产品推荐
相关产品推荐

