我注意到我的“ cors”检查花费的时间比我想象的要长。这与localhost,qa和生产的速度不同。
我正在使用axios(^ 0.18.0),它正在使用mobx / MST / reactjs和asp.net核心api 2.2
我可以使用预检选项,其范围从20毫秒到10秒,它会随机变化。
例如我有
https://localhost:44391/api/Countries
这是一个get请求,它可能连续20毫秒(连续9次)(me ctrl + F5),但是在第10次它决定要花费几秒钟(我在本地主机上实际上并没有得到秒,但有时是一秒钟)
因此,在此测试中,204(cors请求)花费了215ms的时间,而实际返回数据的实际请求花费了一半的时间。似乎倒退了。
这是我的ajax请求
const axiosInstance = axios.create({
baseURL: 'https://localhost:44391/api/Countries',
timeout: 120000,
headers: {
contentType: 'application/json',
}})
axiosInstance.get();
这是我的创业公司。如您所见,在解决此问题后,我将cors全部打开,并希望对其进行优化。
public class Startup
{
public IHostingEnvironment HostingEnvironment { get; }
private readonly ILogger<Startup> logger;
public Startup(IConfiguration configuration, IHostingEnvironment env, ILogger<Startup> logger)
{
Configuration = configuration;
HostingEnvironment = env;
this.logger = logger;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseLazyLoadingProxies();
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});
services.AddIdentity<Employee, IdentityRole>(opts =>
{
opts.Password.RequireDigit = false;
opts.Password.RequireLowercase = false;
opts.Password.RequireUppercase = false;
opts.Password.RequireNonAlphanumeric = false;
opts.Password.RequiredLength = 4;
opts.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
services.AddAuthentication(opts =>
{
opts.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
// standard configuration
ValidIssuer = Configuration["Auth:Jwt:Issuer"],
ValidAudience = Configuration["Auth:Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["Auth:Jwt:Key"])),
ClockSkew = TimeSpan.Zero,
// security switches
RequireExpirationTime = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidateAudience = true
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("CanManageCompany", policyBuilder =>
{
policyBuilder.RequireRole(DbSeeder.CompanyAdminRole, DbSeeder.SlAdminRole);
});
options.AddPolicy("CanViewInventory", policyBuilder =>
{
policyBuilder.RequireRole(DbSeeder.CompanyAdminRole, DbSeeder.SlAdminRole, DbSeeder.GeneralUserRole);
});
options.AddPolicy("AdminArea", policyBuilder =>
{
policyBuilder.RequireRole(DbSeeder.SlAdminRole);
});
});
// do di injection about 30 of these here
services.AddTransient<IService, MyService>();
services.AddSingleton(HostingEnvironment);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddTransient<IValidator<CompanyDto>, CompanyDtoValidator> ();
services.AddTransient<IValidator<BranchDto>, BranchDtoValidator>();
services.AddTransient<IValidator<RegistrationDto>, RegistrationDtoValidator>();
JsonConvert.DefaultSettings = () => {
return new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
};
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
//TODO: Change this.
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseMvc();
}
}
我不知道这是否是一个有效的测试,但它确实模仿了我随机在质量检查/制作中看到的内容。
我更改了axios请求
const axiosInstance = axios.create({
baseURL: 'https://localhost:44391/api/Countries/get',
timeout: 120000,
headers: {
contentType: 'application/json',
}})
axiosInstance.get();
基本上,我放/ get会导致404
但是,当我使用完全相同的场景刷新页面时,它再次以毫秒为单位(尽管仍然比404慢)
答案 0 :(得分:2)
我不确定您是使用负载均衡器还是其他代理服务,但是一个快速的解决方法是将CORS响应标头移到负载均衡器级别。这样可以最大程度地减少您的应用在任何给定时间可能增加的开销。在this answer
中可以找到如何将nginx设置为cors代理服务。答案 1 :(得分:0)
最近我尝试使用 Azure Front Door 作为负载均衡器来解决 CORS 的这个问题。 你可以在这里阅读:
https://www.devcompost.com/post/using-azure-front-door-for-eliminating-preflight-calls-cors
虽然我使用了 Azure Front Door,但您可以使用任何负载均衡器,它可以重新用作入口控制器(如 ng-inx)来解决同样的问题。
基本前提是我正在对 UI 托管域和同一域下的 API 进行负载平衡,从而诱使浏览器认为它是同源调用。因此不再发出 OPTIONS 请求。