我一直在尝试为我的API启用多个来源的CORS而没有任何成功。
这就是我所做的。
创建了CORS政策
[AttributeUsage(AttributeTargets.All, AllowMultiple =false, Inherited =true)]
public class TCCorsPolicyProvider : Attribute, ICorsPolicyProvider
{
private CorsPolicy _policy;
public TCCorsPolicyProvider()
{
_policy = new CorsPolicy
{
SupportsCredentials = true
};
string[] allowedOrigins = "john.doe,ava.wise".Split(',');
string[] allowedMethods = "GET,POST,PUT,OPTIONS".Split(',');
string[] allowedHeaders = "Content-Type,Origin,Authorization,Accept".Split(',');
// Add allowed origins.
foreach (string origin in allowedOrigins)
_policy.Origins.Add(origin);
foreach (string method in allowedMethods)
_policy.Methods.Add(method);
foreach (string header in allowedHeaders)
_policy.Headers.Add(header);
}
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return Task.FromResult(_policy);
}
}
创建工厂
public class TCCorsPolicyProviderFactory : ICorsPolicyProviderFactory
{
ICorsPolicyProvider _provider;
public TCCorsPolicyProviderFactory()
{
_provider = new TCCorsPolicyProvider();
}
public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
{
return _provider;
}
}
在WebApiConfig.cs类中启用了Cors
config.SetCorsPolicyProviderFactory(new TCCorsPolicyProviderFactory());
config.EnableCors();
确保在Global.asax Application_Start中进行适当的注册
GlobalConfiguration.Configure(WebApiConfig.Register);
当上述操作不起作用时,我甚至手动将策略属性应用于我的基本控制器,所有其他控制器都从该控制器继承
[TCCorsPolicyProvider]
public class BaseApiController : ApiController
{
public string IpAddress
{
get { return ContextHelper.GetIpAddress(); }
}
private bool _disposed;
protected virtual void Dispose(bool disposing, Action disposeAction)
{
if (!_disposed)
{
if (disposing)
{
disposeAction();
}
}
_disposed = true;
}
}
但是我收到以下错误(从Angular调用Api)
XMLHttpRequest无法加载hqidwtcdwa01 / api / localizations / reloadCache。 请求中不存在“Access-Control-Allow-Origin”标头 资源。因此,'ava.wise'原因不允许访问。该 响应有HTTP状态码401。
hqidwtcdwa01是目的地,ava.wise是原点。
到目前为止,我发现xmlhttp响应中的http响应头不包含Access-Control-Allow-Origin。但是当我使用HttpCient时,我可以看到标题。
答案 0 :(得分:0)
我和owincontext建立mvc api的问题非常类似,我不得不添加
#if DEBUG //Notice this is only when I'm in debug mode.
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
#endif
但是当我部署了特定于所需来源的添加标头时。
由于您的错误类似,因此可能有助于添加Access-Control-Allow-Origin : ava.wise
标头并检查它是否已解决。希望它有助于缩小您的问题范围。
您希望在标题中包含的内容示例,请注意,选项方法会将已接受的来源提取到任何&#34; *&#34;。
--- --- UPDATE
请尝试更新web.config添加标题。 Custom Headers 这应反映在答复中。显然这在代码中是可能的,但开始很简单。
<configuration> <system.webServer>
<httpProtocol>
<customHeaders>
<remove name="Access-Control-Allow-Origin" />
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
答案 1 :(得分:0)
我相信cors理论上允许多个起源但实际上不允许。对于我的网站,我创建了一个新的CORS属性,并根据传入返回一个允许的来源,这比使用*
更安全 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
AllowMultiple = false)]
public class GlobalEnableCorsAttribute :
Attribute, ICorsPolicyProvider
{
public Boolean SupportsCredentials = true;
public CorsHandler handle = new CorsHandler();
public async Task<CorsPolicy> GetCorsPolicyAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var corsRequestContext = request.GetCorsRequestContext();
var originRequested = corsRequestContext.Origin;
string approvedOrigin = handle.approveCorsOrigin(originRequested);
if(!string.IsNullOrEmpty(approvedOrigin))
{
// Grant CORS request
var policy = new CorsPolicy
{
AllowAnyHeader = true,
AllowAnyMethod = true,
SupportsCredentials = true
};
// add headers
policy.Headers.Add("content-type");
policy.Headers.Add("withcredentials");
policy.Headers.Add("Access-Control-Allow-Headers");
policy.Headers.Add("Access-Control-Allow-Origin");
policy.Headers.Add("Origin");
policy.Headers.Add("Accept");
policy.Headers.Add("X-Requested-With");
policy.Headers.Add("Access-Control-Request-Method");
policy.Headers.Add("Access - Control - Request - Headers");
policy.Origins.Add(approvedOrigin);
return policy;
}
else
{
// Reject CORS request
return null;
}
}
}
原始搜索从服务器配置值
获取允许的来源 public class CorsHandler
{
public string approveCorsOrigin(string providedOrigin)
{
// load list of web.config origins
string fullList = Properties.Settings.Default.CORSOriginPermittedSite;
if (!string.IsNullOrEmpty(fullList))
{
string[] originArray = fullList.Split(new char[]{ ','}, StringSplitOptions.RemoveEmptyEntries);
foreach(string approvedOrigin in originArray)
{
if (providedOrigin.Trim() == approvedOrigin.Trim())
{
return providedOrigin;
}
}
}
return null;
}
}
用法如下
public static void Register(HttpConfiguration config)
{
if (Properties.Settings.Default.CORSOriginPermittedSite != null && !string.IsNullOrWhiteSpace(Properties.Settings.Default.CORSOriginPermittedSite))
{
var cors = new GlobalEnableCorsAttribute();
config.EnableCors(cors);
}
}
最后这个代码是针对webapi设置的,但是应该具有可比性,你也(如果使用类似的话)需要让飞行前应对相同的原始搜索..
答案 2 :(得分:0)
我是用肮脏的方式做到的,也许不是那个建议但是这让我走了(假设你安装了cors nuget,web api 2.0和.NET 4.5):
的web.config:
<appSettings>
<add key="AllowedDomains" value="http://domain0:8009, http://domain1:8009"/>
</appSettings>
Configs.cs:
public static string AllowedDomains {
get {
return @ConfigurationManager.AppSettings["AllowedDomains"].ToString();
}
}
WebApiConfig:
public static void Register(HttpConfiguration config)
{
var attribute = new System.Web.Http.Cors.EnableCorsAttribute(Configs.AllowedDomains, "*", "*"); //domains, headers, methods - you could do the same for the other args.
config.EnableCors(attribute); //global
}
要按Controller / action进行过滤,只需在顶部添加属性:
[System.Web.Http.Cors.EnableCors(origins: "http://domain2:8009", headers: "*", methods: "*")]
让我知道任何进展或评论。希望这可以帮助。谢谢! :)