迁移问题
在ASP.NET 4.x时期,解决CORS问题是非常容易的,仅需在配置文件web.config里增加相应的配置节点即可,无法在程序中进行编码。在ASP.NET Core中,一切都是DI+配置Options化,确实有些不太习惯,也没有时间研究CORS配置化实现方法。所以只能把CORS配置项保存到appsettings.json文件里,然后在代码中编码实现CORS功能,因此,本文重点记录实现过程。
解决方案
1.ASP.NET 4.x时期web.config文件配置CORS
<system.webServer> <httpProtocol> <customHeaders> <!--多个对象用英文逗号分隔--> <add name="Access-Control-Allow-Origin" value="*" /> <!--若为true,Origin节点不能为*--> <add name="Access-Control-Allow-Credentials" value="false" /> <!--多个对象用英文逗号分隔--> <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,HEAD,OPTIONS" /> <!--多个对象用英文逗号分隔--> <add name="Access-Control-Allow-Headers" value="X-Requested-With,origin,content-length,content-type,accept,Authorization,ApplicationType,LanguageType" /> <!--前端可以通过getResponseHeader读取值--> <add name="Access-Control-Expose-Headers" value="Set-Token" /> <!--用来指定本次预检请求的有效期(20天),单位为秒,设置后有效期内不在发预检查请求--> <add name="Access-Control-Max-Age" value="2592000" /> </customHeaders> </httpProtocol> </system.webServer>
2.ASP.NET Core的玩法
1)在appsettings.json文件里配置好CORS项
{ //配置CORS策略 "CorsPolicy": { //多个对象用英文逗号分隔 "AllowOrigins": "*", //若为true,Origin节点不能为* "AllowCredentials": "false", //多个对象用英文逗号分隔 "AllowMethods": "GET,PUT,POST,DELETE,HEAD,OPTIONS", //多个对象用英文逗号分隔 "AllowHeaders": "X-Requested-With,origin,content-length,content-type,accept,Authorization,ApplicationType,LanguageType", //前端可以通过getResponseHeader读取值 "ExposeHeaders": "Set-Token",
//用来指定本次预检请求的有效期(20天),单位为秒,设置后有效期内不在发预检查请求
"MaxAge": 8640000
} }
2)定义CORS策略对应的Options类CorsPolicyOptions
public class CorsPolicyOptions { public string AllowOrigins { get; set; } = "*"; public bool AllowCredentials { get; set; } = false; public string AllowMethods { get; set; } = "GET,PUT,POST,DELETE,HEAD,OPTIONS"; public string AllowHeaders { get; set; } = "X-Requested-With,origin,content-length,content-type,accept,Authorization"; public string ExposeHeaders { get; set; } = "Set-Token"; public int MaxAge { get; set; } = 8640000; }
3)定义appsettings.json文件对应的AppSettings类文件,在AppSettings类的私有类里实现CORS策略的读取
public class AppSetting { private static object _objLocker = new object(); private static AppSetting _instance; private AppSetting() { } public static AppSetting Instance { get { if (_instance == null) { lock (_objLocker) { if (_instance == null) { _instance = new AppSetting(); AppSettingConfig.Load(_instance); } } } return _instance; } } private class AppSettingConfig { private static AppSetting _appSetting; public static void Load(AppSetting appSetting) { _appSetting = appSetting; Compute(); ChangeToken.OnChange(() => ConfigObjectManager.Instance.AppSetting.GetReloadToken(), () => { Change(); }); } private static void Compute() { _appSetting.CorsPolicy = ConfigObjectManager.Instance.AppSetting.GetSection(ConstFiles.AppSettings_CorsPolicy).Get<CorsPolicyOptions>(); } private static void Change() { } } #region Object Propertries public CorsPolicyOptions CorsPolicy { get; private set; } #endregion }
4)配置CORS
public static void Config(IServiceCollection services) { if (AppSetting.Instance.CorsPolicy != null) { services.AddCors(options => { options.AddDefaultPolicy(bd => { if ("*" == AppSetting.Instance.CorsPolicy.AllowOrigins) { bd.SetIsOriginAllowed(_ => true); } else { var _tmpArray = AppSetting.Instance.CorsPolicy.AllowOrigins.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); bd.WithOrigins(_tmpArray); } if (AppSetting.Instance.CorsPolicy.AllowCredentials) { bd.AllowCredentials(); } else { bd.DisallowCredentials(); } var _tmpMethods = AppSetting.Instance.CorsPolicy.AllowMethods.IsNotNullEmptyWhiteSpace() ? AppSetting.Instance.CorsPolicy.AllowMethods : "GET,PUT,POST,DELETE,HEAD,OPTIONS"; bd.WithMethods(_tmpMethods); var _tmpHeaders = AppSetting.Instance.CorsPolicy.AllowHeaders.IsNotNullEmptyWhiteSpace() ? AppSetting.Instance.CorsPolicy.AllowHeaders : "X-Requested-With,origin,content-length,content-type,accept,Authorization,ApplicationType,LanguageType"; bd.WithHeaders(_tmpHeaders); var _tmpExposedHeaders = AppSetting.Instance.CorsPolicy.ExposeHeaders.IsNotNullEmptyWhiteSpace() ? AppSetting.Instance.CorsPolicy.ExposeHeaders : ""; bd.WithExposedHeaders(_tmpExposedHeaders); var _tmpMaxAge = AppSetting.Instance.CorsPolicy.MaxAge > 1440 ? AppSetting.Instance.CorsPolicy.MaxAge : 8640000; bd.SetPreflightMaxAge(TimeSpan.FromSeconds(_tmpMaxAge)); }); }); } }
5)启用CORS
public static void Start(IApplicationBuilder app) { if (AppSetting.Instance.CorsPolicy != null) { app.UseCors(); } }
总结
CORS在ASP.NET Core中实现还是比较简单的,只是习惯了不把可以配置化实现的代码写死在代码中,所以才有了上述编码逻辑。在上述代码中,我比较满意巨硬提供把配置文件中的对象转换为类对象这个操作的,想起在ASP.NET 4.x项目中都是手动实现,特别说明:咋ASP.NET 4.x项目中使用的配置文件格式ini。
标签:跨域,2core,Instance,CorsPolicy,AppSetting,static,CORS,public From: https://www.cnblogs.com/Jkinbor/p/16772096.html