带 Cors 的跨域请求
Posted
技术标签:
【中文标题】带 Cors 的跨域请求【英文标题】:Cross Domain Request w/ Cors 【发布时间】:2016-05-05 03:53:02 【问题描述】:我有一个 ember 解决方案,它在 http://localhost:4200 上本地运行。它从我的使用 Windows 身份验证的 WebApi 应用程序请求数据。目前在http://localhost:11470 上运行。由于某些奇怪的原因,当我的 WebApi 应用程序响应时,它会遗漏以下内容,例如:Access-Control-Allow-Origin
。从而抛出以下异常:
XMLHttpRequest 无法加载 http://localhost:11470/api/Authentication/logins。回应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:4200” 使用权。响应的 HTTP 状态代码为 401。
如果我查看请求,我清楚地看到 WebApi 应用程序未在标头中包含此类数据。我该如何纠正我的问题?
// Inside: 'WebApiConfig'
configuration.EnableCors(new EnableCorsAttribute("http://localhost:4200", "*", "*") SupportsCredentials = true );
// Controller:
[Route("api/Authentication/Logins")]
public IHttpActionResult Login()
if (User.Identity.IsAuthenticated)
return Ok();
return Unauthorized();
// Ember Ajax:
Ember.$.ajax(
type: "GET",
url: 'http://localhost:11470/api/Authentication/logins',
crossDomain: true,
headers:
'Authorization': 'WWW-authenticate'
,
xhrFields:
withCredentials: true
,
error: function() console.log('Error'); ,
success: function() console.log('Working?');
);
我什至尝试了以下方法:
强制web.config
中的标头信息。
IHttpActionResult
的自定义实现
ActionFilterAttribute
的自定义过滤器实现。
那些在控制台错误之前没有命中。为 WebApi 应用程序启用的所有功能都是 Windows 身份验证,如果我直接导航到 localhost:11470/api/authentication/login,它会提示我输入我的 Active Directory 凭据,然后正确响应。
我已经阅读了几篇文档,例如:
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api https://msdn.microsoft.com/en-us/magazine/dn532203.aspx?f=255&MSPPError=-2147217396 http://www.html5rocks.com/en/tutorials/cors/我无法找到可靠工作的解决方案,我缺少什么或不理解什么?我知道它需要标头,但是为什么 WebApi 的 Cors 库没有发送它?
【问题讨论】:
为什么不在开发中使用 ember-cli 中的--proxy
,因为在生产中您希望将 ember 应用程序托管在与 asp.NET 应用程序相同的 IIS 中?
这仍然会导致同样的错误,是的,你是对的,我可以在同一个 IIS 应用程序池和实例中同时运行。但我想了解我遇到这种情况的原因。
您能否在进行 AJAX 调用时提供有关请求/响应标头的更多信息,可能正在使用 fiddler 之类的工具
基本上你的请求头应该有 Origin: localhost:4200 并且响应头应该有 Access-Control-Allow-Origin: localhost:4200 或 *
@CleanCrispCode 是的,我可以,我知道我需要 Access-Control-Allow-Origin
,但由于某些奇怪的原因,我的 WebApi 没有将其发回。
【参考方案1】:
添加包
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Cors" version="5.2.3" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Cors" version="5.2.3" targetFramework="net461" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net461" />
</packages>
public static void Register(HttpConfiguration config)
config.MapHttpAttributeRoutes();
//config.EnableCors();
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/controller/id",
jQuery
url: ApiPath + "/api/Orders/OrderNumber/" + orderNo,
dataType: "json",
crossDomain: true,
headers: "__RequestVerificationToken": AntiForgery.getToken() ,
//headers: "__RequestVerificationToken": AntiForgery.getToken() ,
success: function (data)
$.each(data.ItemList, function (key, value)
SettingArrayLists(value);
【讨论】:
【参考方案2】:我在使用 Microsoft.AspNet.WebApi.Cors 包时遇到了完全相同的问题。
尝试检查 Web API 的一些事情(您提到的一些您尝试过,但我将它们与我尝试过的详细信息一起列出,以防细节存在差异):
如果您的 API 我们使用登录信息,您需要允许 CORS 通过 SupportsCendentials 属性发送“身份验证”标头,应该通过以下方式启用:
config.EnableCors(new EnableCorsAttribute("http://localhost:4200", "", "") SupportsCredentials = true );
但是这个解决方案实际上并没有为我工作,它没有在我的 /token OPTIONS 飞行前设置 CORS 标头,但它可能与库或 WebAPI 版本存在版本差异。
-
在您的 Web.config 中检查您是否正在禁用 OPTIONS 处理程序(我认为这是默认行为),这是飞行前尝试调用的:
在 system.webServer.handlers 下:
<!--<remove name="OPTIONSVerbHandler" />--> <!--Allow options handling (preflight requests) by removing this line-->
-
强制它:在 system.webServer.httpProtocol 下为您的自定义标头添加所有这些以强制它们通过(如果您尝试这样做,请禁用其他 CORS 选项)。
<customHeaders>
<!--Enable CORS for all requests (TODO Fix this, move to OWIN settings) -->
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, Content-Type, Authorization" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
</customHeaders>
这些更改允许我的 API 以正确的标头响应,我建议从那里开始。
而不是使用 Microsoft.AspNet.WebApi.Cors CORS 包并将其设置在 WebApiConfig.cs 中,您可以直接在 Startup.cs 或 Startup.Auth.cs 中的 OWIN 中间位置上设置它,并且作为 FIRST 行中的任何一个,在任何其他 OWIN pineline 之前,添加:
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
【讨论】:
以上是关于带 Cors 的跨域请求的主要内容,如果未能解决你的问题,请参考以下文章
使用 Angular 和 NodeJs (CORS) 的跨域请求