最近在尝试将站点的后台管理前后端分离,并且将后台改为asp.net core webapi形式,发现其中一些坑。首先肯定要支持跨域,虽然可以用代理实现,但毕竟代码是自己的,可以修改。
首先需要在Startup.cs 的ConfigureServices 方法中加入
services.AddCors(options => { options.AddPolicy("any", builder => { builder.AllowAnyOrigin() //允许任何来源的主机访问 //builder.WithOrigins("http://localhost:8080") ////允许http://localhost:8080的主机访问 .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials();//指定处理cookie }); });
然后在下面Configure 方法加入 app.UseCors("any");
以为这样就可以,没想到还是报错,于是加入了一个过滤器用来在Header中加入Access-Control-Allow-Origin 等
using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Blogs.Service.Manage { public class CorsActionFilter : IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { } public void OnActionExecuting(ActionExecutingContext context) { string referer = context.HttpContext.Request.Headers["Referer"].ToString(); if (!String.IsNullOrEmpty(referer)) { context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin",Regex.Match(referer,"(https{0,1}://.*?)/").Groups[1].Value); context.HttpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true"); //这个为true Access-Control-Allow-Origin 不能设置 * context.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "*"); //GET, HEAD, OPTIONS, POST, PUT context.HttpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*"); //Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers } else { context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); context.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "*"); context.HttpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*"); } } } }
然后再Startup中的ConfigureServices 方法加入
services.AddMvc(config=>
{
config.Filters.Add(new CorsActionFilter());
})
需要注意的是Access-Control-Allow-Credentials 为true的时候Access-Control-Allow-Origin 不能为 * 自己以前也不知道,Credentials主要作用是 js请求的时候带上Cookie 这样服务端就可以是谁了,如axios的axios.defaults.withCredentials=true;
貌似不做第一步只做第二步 Get 方法也不会有问题,但post 会不成功。
还遇到过返回401的,连方法体都不进
我发现在POST的时候会有一个Options请求,但是会报404 于是在方法上加了[HttpOptions] 但是偶然发现这样会执行两次,而且实体参数取不到值,后来在Controller上加上ApiController 特性,再去掉HttpOptions 才成功,可能上面说的不一定全,具体可以一个一个试........
还有一个问题我发现Session存了值后下次取不到,网上查是去掉Startup中ConfigureServices方法的这段
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
以此记录下。