1 Framework.Infrastructure.Middleware.CorsExceptionHandlerMiddleware
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Http;
namespace Framework.Infrastructure.Middleware
{
/// <summary>
/// 【跨域异常处理中间件--类】
/// <remarks>
/// 摘要:
/// 该管道中间件类主要为了集中解决在由vue/uni-app前端项目跨域(Cors)访问当前后端项目时,浏览器或App中出现的异常:
/// 1、“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”。
/// 2、“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”。
/// 3、“has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.”。
/// 说明:
/// vue/uni-app前端项目跨域(Cors)访问当前后端项目时,浏览器或App中出现的异常,可以直接在 vue/uni-app前端项目中解决;但本人更习惯通过后端定义来集中解决这些异常。
/// </remarks>
/// </summary>
public class CorsExceptionHandlerMiddleware
{
#region 拷贝构造方法与变量
/// <summary>
/// 【下1个】
/// <remarks>
/// 摘要:
/// .Net(Core)框架内置管道中的下1个管道中间件实例。
/// </remarks>
/// </summary>
private readonly RequestDelegate _next;
///<param name="next">.Net(Core)框架内置管道中的下1个管道中间件实例。</param>
/// <summary>
/// 【拷贝构造方法】
/// <remarks>
/// 摘要:
/// 通过该构造方法中的参数实例,实例化.Net(Core)框架内置管道中的下1个管道中间件实例。
/// </remarks>
/// </summary>
public CorsExceptionHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
#endregion
#region 方法
///<param name="context">HTTP上下文实例。</param>
/// <summary>
/// 【异步调用】
/// <remarks>
/// 摘要:
/// 通过该方法向.Net(Core)框架内置管道中集成当前管道中间件,集中解决在由vue/uni-app前端项目跨域(Cors)访问当前后端项目时,浏览器或App中出现的异常:
/// 1、“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”。
/// 2、“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”。
/// 3、“has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.”。
/// </remarks>
/// </summary>
public async Task InvokeAsync(HttpContext context)
{
//解决在由Hbuilder创建的前端Xuni-app项目(Cors)访问当前后端项目时,浏览器或App中会出现异常:
//“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”。
if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Headers"))
{
context.Response.Headers.Add("Access-Control-Allow-Headers", "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization");
}
if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Methods"))
{
context.Response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH,OPTIONS");
}
//解决在由Hbuilder创建的前端Xuni-app项目(Cors)访问当前后端项目时,浏览器或App中会出现异常:
//“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”。
if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Origin"))
{
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
}
if (context.Request.Headers.ContainsKey(CorsConstants.Origin))
{
//解决在前端通过“axios.post”方式调用后端POST-API有,如果前端“axios.post”方法没有加载“headers”参数实例,下1行语句中的配置,否则“axios.post”方法,访问后端的POST-API,否则会出现:"HTTP:415"错误。
context.Request.ContentType = "application/json";
//解决在由Hbuilder创建的前端Xuni-app项目(Cors)访问当前后端项目时,浏览器或App中会出现异常:
//“' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.”。
if (context.Request.Method.Equals("OPTIONS"))
{
context.Response.StatusCode = StatusCodes.Status200OK;
return;
}
}
await _next(context);
}
#endregion
}
}
2 Framework.Infrastructure.Middleware.CorsExceptionHandlerStartup
using Core.Infrastructure;
using Framework.Infrastructure.Middleware;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Framework.Infrastructure
{
/// <summary>
/// 【跨域异常处理启动--类】
/// <remarks>
/// 摘要:
/// 通过该类中的管道方法成员,抽离自定义跨域异常处理管道中间件,为当前程序集中解决在由vue/uni-app前端项目跨域(Cors)访问当前后端项目时,浏览器或App中出现的异常,提供管道实例支持。
/// </remarks>
/// </summary>
public class CorsExceptionHandlerStartup : IStartup
{
#region 属性--接口实现
/// <summary>
/// 【顺序】
/// <remarks>
/// 摘要:
/// 获取数据库启动类中管道中间件实例,被集成到内置管道实例中的顺序,默认值:200。
/// 注意:
/// .NetCore框架默定义了一些常用的内置管道中间件,并默认规定了这些内置管道中间件实例在内置管道实例中被调用的顺序,
/// 如果不按照该默认顺序调用这些内置管道中间件,在程序执行时就会出现逻辑异常。
/// </remarks>
/// </summary>
public int Order => 200;
#endregion
#region 方法--接口实现
/// <param name="services">.Net(Core)框架内置依赖注入容器实例。</param>
/// <param name="configuration">.NetCore框架内置配置接口实例(存储着当前程序中所有*.json文件中的数据)。</param>
/// <summary>
/// 【配置服务】
/// <remarks>
/// 摘要:
/// 由于该类中所需要的实例,已经注入到内置容器中,所以该方法成员中没有依赖注入中间件/实例需要注入到内置依赖注入容器中。
/// </remarks>
/// </summary>
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
}
/// <param name="application">.NetCore框架内置管道接口实例。</param>
/// <summary>
/// 【配置】
/// <remarks>
/// 摘要:
/// 该方法把集中解决在由vue/uni-app前端项目跨域(Cors)访问当前后端项目时,浏览器或App中出现的异常的“应/答”操作所需要管道中间件集成到内置管道中间件中。
/// </remarks>
/// </summary>
public void Configure(IApplicationBuilder application)
{
application.UseMiddleware<CorsExceptionHandlerMiddleware>();
}
#endregion
}
}
对以上功能更为具体实现和注释见:230207_031shopDemo(抽离跨域异常处理管道中间件之CorsExceptionHandlerMiddleware)。