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的主要内容,如果未能解决你的问题,请参考以下文章

PHP没有按顺序执行

跨域请求被阻止 Symfony/AngularJS

C# MVC js 跨域

PHP Ajax 跨域问题最佳解决方案

PHP Ajax 跨域问题最佳解决方案

PHP Ajax 跨域问题最佳解决方案