IE:“在 Access-Control-Allow-Origin 标头中找不到来源”使用启用 CORS 的 .NET Core 和 Angular 2

Posted

技术标签:

【中文标题】IE:“在 Access-Control-Allow-Origin 标头中找不到来源”使用启用 CORS 的 .NET Core 和 Angular 2【英文标题】:IE: "Origin not found in Access-Control-Allow-Origin header" using CORS enabled .NET Core and Angular 2 【发布时间】:2017-05-25 08:59:28 【问题描述】:

我正在构建一个内部应用程序,我正在使用 Angular 2 (CLI/Webpack) 调用我使用 .NET Core 构建的支持 CORS 的服务。该服务使用用户的集成 Windows 身份验证凭据来查找有关该用户的信息并将其返回给 Angular。在 Chrome 和 Firefox 中一切正常,但在 IE 10 和 11 中,我收到带有消息 Origin http://localhost:4200 not found in Access-Control-Allow-Origin header. 的“401 Unauthorized”响应

在 Angular 中,我正在像这样进行 HTTP 调用:

private options = new RequestOptions(withCredentials: true);    

let getURL = `server:port/api/users/username`;
return this.http
    .get(getURL, this.options)
    .map((response: Response) => response.json()[0])
    .catch(this.handleError);

我的 .NET Core 服务在 Startup.cs 中使用以下代码:

public void ConfigureServices(IServiceCollection services)

    services.AddCors(options =>
    
        options.AddPolicy("policyAnyone",
            builder => 
                builder.AllowCredentials()
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader();
            );
    );

    services.AddApplicationInsightsTelemetry(Configuration);

    services.AddMvc();


public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseCors("policyAnyone");

    app.UseApplicationInsightsRequestTelemetry();

    app.UseApplicationInsightsExceptionTelemetry();

    app.UseMvc();

然后控制器使用它通过User.FindFirst(ClaimTypes.Name).Value 接收到的用户名,运行一个存储过程,并返回结果。

作为参考,Chrome 有以下请求标头:

Accept: application/json, text/plain, `*/*`
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Authorization: Negotiate %lotsOfEncodedText%
Cache-Control: max-age=0
Connection: keep-alive
content-type: text/plain
Host: server:port
Origin: http://localhost:4200
Referer: http://localhost:4200/dashboard
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/49.0.2623.87 Safari/537.36

IE 有这些:

Request: GET /api/users/username HTTP/1.1
Accept: application/json, text/plain, `*/*`
Content-Type: text/plain
Referer: http://localhost:4200/dashboard
Accept-Language: en-US
Origin: http://localhost:4200
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: server:port
Connection: Keep-Alive
Cache-Control: no-cache

似乎 CORS 配置正确,并且我的 Angular 设置非常简单,但 IE 甚至不显示凭据框。

【问题讨论】:

【参考方案1】:

如果有人遇到这个问题,我想我能够解决这个问题。我的问题是我的 PC 的 Internet 选项,其中登录身份验证选项(Internet 选项 > 安全 > 自定义级别... > 用户身份验证 > 登录)设置为“仅在 Intranet 区域中自动登录”。虽然这是有意的,但 IE 并未将我的网站视为 Intranet 站点,而是将其视为 Internet 站点。原因在于 IE 使用的“点规则”。

“如果 URI 的主机名不包含任何句点(例如 http://team/),则它被映射到本地 Intranet 区域。” [1]

我们本地站点的主机名包含句点,因此映射到 Internet 区域。在我们能够消除繁文缛节之后,手动将我的站点添加到本地 Intranet 区域(Int​​ernet 选项 > 安全 > 本地 Intranet > 站点 > 高级)应该可以解决我的问题。

我不确定为什么 IE 决定使用它所做的 CORS ACAO 错误消息进行响应,但 401:未经授权的响应至少足以让我离开。

[1] 互联网选项信息:https://support.microsoft.com/en-us/help/258063/internet-explorer-may-prompt-you-for-a-password

[2] Intranet Zone 确定信息:https://blogs.msdn.microsoft.com/ieinternals/2012/06/05/the-intranet-zone/

【讨论】:

【参考方案2】:

IE 对待端口的方式与其他浏览器不同。其他浏览器说,如果端口不同,那么它就不是同一个“来源”。在IE中,如果端口不同但域相同,那么它是同源的,并且不使用标头。

您可以在这里阅读更多内容:https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#IE_Exceptions

但是,您仍然应该通过 Angular 看到返回的数据(因为 IE 只会将它们视为同源)。那么您是否从您的 ajax 调用中看到了响应数据?

【讨论】:

是的,我在另一个答案中也看到了,但是服务的来源是不同的服务器,所以域应该不同。我也没有看到任何来自 IE 的返回数据,所以我认为这不是问题所在。应用程序在 401 之后完全出错,即使我完全不依赖调用的结果并且之后没有运行任何函数。

以上是关于IE:“在 Access-Control-Allow-Origin 标头中找不到来源”使用启用 CORS 的 .NET Core 和 Angular 2的主要内容,如果未能解决你的问题,请参考以下文章

让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法

让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法

让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法

转载------让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法

一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10

ie11兼容模式ie8显示错误