Access-Control-Allow-Origin - 多个域访问 MVC web api 2
Posted
技术标签:
【中文标题】Access-Control-Allow-Origin - 多个域访问 MVC web api 2【英文标题】:Access-Control-Allow-Origin - mutiple domains to access MVC web api 2 【发布时间】:2017-10-02 04:53:03 【问题描述】:我需要通过我的 Web API 允许来自多个域的 CORS 请求。但是,我不想通过在 web config 中执行以下操作来让它对所有人开放。
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
</customHeaders>
</httpProtocol>
</system.webServer>
我只需要允许域的白名单能够向我的 API 发出 CORS 请求。
我见过this SO question,但是,我不希望使用.htaccess
文件,因为我无法控制 IIS 服务器。
我已经尝试过this SO answer 和this blog。
问题是,它总是返回以下错误。
请求的资源上不存在“Access-Control-Allow-Origin”标头。
这是我的实现。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class EnableCORSAttribute : ActionFilterAttribute
private string[] origins;
private string[] methods;
public EnableCORSAttribute(string[] origins = null, string[] methods = null)
this.origins = origins;
this.methods = methods;
public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
if (origins == null || !origins.Any())
//Allow all
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
else if (origins.Contains(HttpContext.Current.Request.Url.Host, StringComparer.InvariantCultureIgnoreCase))
//Allow only if matching
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Url.Host);
if (methods == null || !methods.Any())
//Allow all
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Methods", "*");
else if (methods.Contains(HttpContext.Current.Request.HttpMethod, StringComparer.InvariantCultureIgnoreCase))
//Allow only specified
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Methods", HttpContext.Current.Request.HttpMethod);
这就是我用属性装饰我的BaseController
的方式。
[EnableCORS(origins: new string[] "localhost" , methods: new string[] "GET", "POST", "OPTIONS" )]
public class BaseController : ApiController
// GET api/<controller>
public HttpResponseMessage Options()
return new HttpResponseMessage StatusCode = HttpStatusCode.OK ;
我也尝试从Global.asax
文件中注册此属性。
GlobalFilters.Filters.Add(new EnableCorsAttribute());
RegisterGlobalFilters(GlobalFilters.Filters);
但仍然得到同样的错误。不知道我还缺少什么。
我也尝试过Microsoft.AspNet.WebApi.Cors
Nuget 包并将其放入 WebApiConfig 文件中。
var enableCorsAttribute = new EnableCorsAttribute("http://localhost:59427",
"Origin, Content-Type, Accept, Authorization",
"GET, POST, OPTIONS");
config.EnableCors(enableCorsAttribute);
它适用于一个域,但一旦我添加另一个域,它也会开始抛出相同的错误。
【问题讨论】:
如果需要,我还可以发布我的 javascript 代码和从其他域调用的实际控制器方法。 【参考方案1】:结果比我想象的要简单。
我需要做的就是查看请求和响应标头。
我尝试添加以允许 CORS
请求的另一个域正在发送一些自定义标头。
所以我允许了那些特定的自定义标题并且它起作用了。
这是最终的解决方案。
我的BaseController
// No fancy decoration here... :)
public class BaseController : ApiController
// GET api/<controller>
public HttpResponseMessage Options()
return new HttpResponseMessage StatusCode = HttpStatusCode.OK ;
我的WebApiConfig
public static class WebApiConfig
public static void Register(HttpConfiguration config)
//Some API routes here...
var enableCorsAttribute = new EnableCorsAttribute(
// Comma separated whitelist of allowed domains, notice no slash ('/') at the end of domain
"http://local.ui.two:9003,http://local.ui.one:9001",
// Allowed Custom Headers
"Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control, If-Modified-Since, Pragma",
// Allowed methods
"GET, PUT, POST, DELETE, OPTIONS"
);
config.EnableCors(enableCorsAttribute);
并在Global.asax
注册了这个WebApiConfig。
protected void Application_Start()
GlobalConfiguration.Configure(WebApiConfig.Register);
web.config
中不需要任何内容
不需要编写自定义的花哨属性,为什么要重新发明***!? :)
仅使用 Nuget 包Microsoft.AspNet.WebApi.Cors
我问过的This other question 和两位站出来帮助社区的天才,给了我正确的方向。
【讨论】:
以上是关于Access-Control-Allow-Origin - 多个域访问 MVC web api 2的主要内容,如果未能解决你的问题,请参考以下文章