Setting Access-Control-Allow-Origin in ASP.Net MVC - simplest possible method
我有一个简单的actionmethod,返回一些json。 它在ajax.example.com上运行。 我需要从另一个站点someothersite.com访问它。
如果我试着打电话给我,我会得到预期的......:
1 | Origin http://someothersite.com is not allowed by Access-Control-Allow-Origin. |
我知道有两种解决方法:JSONP和创建自定义HttpHandler
设置标题。
有没有更简单的方法?
简单的动作是否不可能定义允许的起源列表 - 或者简单地允许每个人? 也许一个动作过滤器?
最佳将是......:
1 | return json(mydata, JsonBehaviour.IDontCareWhoAccessesMe); |
对于普通的ASP.NET MVC控制器
创建一个新属性
1 2 3 4 5 6 7 8 | public class AllowCrossSiteJsonAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin","*"); base.OnActionExecuting(filterContext); } } |
标记您的行动:
1 2 3 4 5 | [AllowCrossSiteJson] public ActionResult YourMethod() { return Json("Works better?"); } |
对于ASP.NET Web API
1 2 3 4 5 6 7 8 9 10 11 12 13 | using System; using System.Web.Http.Filters; public class AllowCrossSiteJsonAttribute : ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { if (actionExecutedContext.Response != null) actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin","*"); base.OnActionExecuted(actionExecutedContext); } } |
标记整个API控制器:
1 2 3 | [AllowCrossSiteJson] public class ValuesController : ApiController { |
或单个API调用:
1 2 3 4 5 | [AllowCrossSiteJson] public IEnumerable<PartViewModel> Get() { ... } |
对于Internet Explorer <= v9
IE <= 9不支持CORS。我写了一个javascript,它会自动通过代理路由这些请求。这一切都是100%透明的(你只需要包含我的代理和脚本)。
使用nuget
博客文章|源代码
如果您使用的是IIS 7+,则可以在system.webServer部分中将web.config文件放入该文件夹的根目录中:
1 2 3 4 5 6 | <httpProtocol> <customHeaders> <clear /> </customHeaders> </httpProtocol> |
请参阅:http://msdn.microsoft.com/en-us/library/ms178685.aspx
并且:http://enable-cors.org/#how-iis7
我遇到了一个问题,浏览器拒绝提供它在cookie中传递请求时检索到的内容(例如,xhr的
基于@jgauffin的答案,我创建了这个,这基本上是一种解决特定浏览器安全检查的方法,因此需要注意。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class AllowCrossSiteJsonAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { // We'd normally just use"*" for the allow-origin header, // but Chrome (and perhaps others) won't allow you to use authentication if // the header is set to"*". // TODO: Check elsewhere to see if the origin is actually on the list of trusted domains. var ctx = filterContext.RequestContext.HttpContext; var origin = ctx.Request.Headers["Origin"]; var allowOrigin = !string.IsNullOrWhiteSpace(origin) ? origin :"*"; ctx.Response.AddHeader("Access-Control-Allow-Origin", allowOrigin); ctx.Response.AddHeader("Access-Control-Allow-Headers","*"); ctx.Response.AddHeader("Access-Control-Allow-Credentials","true"); base.OnActionExecuting(filterContext); } } |
这非常简单,只需在web.config中添加即可
1 2 3 4 5 6 7 8 9 10 | <system.webServer> <httpProtocol> <customHeaders> </customHeaders> </httpProtocol> </system.webServer> |
在Origin中放置了所有可以访问您的Web服务器的域,
在标头中放置任何ajax http请求可以使用的所有可能的标头,
在方法中将您允许的所有方法放在服务器上
问候 :)
WebAPI 2现在有一个CORS包,可以使用以下命令安装:
安装包Microsoft.AspNet.WebApi.Cors -pre -project WebServic
安装完成后,请按照以下代码进行操作:http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
有时OPTIONS动词也会导致问题
只是:
使用以下内容更新web.config
1 2 3 4 5 6 7 8 | <system.webServer> <httpProtocol> <customHeaders> </customHeaders> </httpProtocol> </system.webServer> |
并使用httpGet和httpOptions更新webservice / controller标头
1 2 3 4 | // GET api/Master/Sync/?version=12121 [HttpGet][HttpOptions] public dynamic Sync(string version) { |
本教程非常有用。快速总结一下:
使用Nuget上提供的CORS包:
在
将属性添加到您需要处理cors的控制器:
1 2 3 4 5 6 7 8 | public ActionResult ActionName(string ReqParam1, string ReqParam2, string ReqParam3, string ReqParam4) { this.ControllerContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin","*"); /* --Your code goes here -- */ return Json(new { ReturnData="Data to be returned", Success=true }, JsonRequestBehavior.AllowGet); } |
如果您使用的是API,请将此行添加到您的方法中。
1 | HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*"); |
There are different ways we can pass the
Access-Control-Expose-Headers.
- 正如jgauffin所解释的那样,我们可以创建一个新属性。
- 正如LaundroMatt所解释的那样,我们可以添加web.config文件。
-
另一种方法是我们可以在webApiconfig.cs文件中添加如下代码。
config.EnableCors(new EnableCorsAttribute(",headers:",methods:"*",exposedHeaders:"TestHeaderToExpose"){SupportsCredentials = true});
或者我们可以在Global.Asax文件中添加以下代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 | protected void Application_BeginRequest() { if (HttpContext.Current.Request.HttpMethod =="OPTIONS") { //These headers are handling the"pre-flight" OPTIONS call sent by the browser HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers","*"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials","true"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","http://localhost:4200"); HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers","TestHeaderToExpose"); HttpContext.Current.Response.End(); } } |
我已经为选项编写了它。请根据您的需要进行修改。
快乐编码!!
如果你使用IIS,我建议尝试IIS CORS模块。
它易于配置,适用于所有类型的控制器。
以下是配置示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <system.webServer> <cors enabled="true" failUnlistedOrigins="true"> <add origin="https://*.microsoft.com" allowCredentials="true" maxAge="120"> </allowHeaders> </allowMethods> <exposeHeaders> </exposeHeaders> </add> </cors> </system.webServer> |
在Web.config中输入以下内容
1 2 3 4 5 6 7 8 | <system.webServer> <httpProtocol> <customHeaders> <clear /> </customHeaders> </httpProtocol> |