我的 Cors 预检选项请求似乎很慢

cho*_*bo2 5 performance cors asp.net-core axios asp.net-core-2.0

我注意到“cors”检查花费的时间比我预期的要长。本地主机、质量保证和生产以不同的速度发生这种情况。

我正在使用 axios (^0.18.0),它使用 mobx/MST/reactjs 和 asp.net core api 2.2

我可以设置范围从 20 毫秒到 10 秒的预检选项,并且它会随机变化。

例如我有

https://localhost:44391/api/Countries
Run Code Online (Sandbox Code Playgroud)

这是一个 get 请求,它可能需要 20 毫秒,连续 9 次(我 ctrl + F5),但在第 10 次它决定花费几秒钟(我在本地主机上没有真正得到秒,但有时是一秒钟)。

在此输入图像描述

因此,在这个测试中,204(cors 请求)需要 215 毫秒,而带回数据的实际请求只需要一半时间。这看起来倒退了。

在此输入图像描述

在此输入图像描述

这是我的ajax请求

 const axiosInstance = axios.create({
      baseURL: 'https://localhost:44391/api/Countries',
      timeout: 120000,
      headers: {
        contentType: 'application/json',
      }})

      axiosInstance.get();
Run Code Online (Sandbox Code Playgroud)

这是我的启动。我把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();

        }
    }
Run Code Online (Sandbox Code Playgroud)

我不知道这是否是一个有效的测试,但它确实模仿了我在随机时间在质量保证/生产中看到的情况。

我将 axios 请求更改为...

 const axiosInstance = axios.create({
      baseURL: 'https://localhost:44391/api/Countries/get',
      timeout: 120000,
      headers: {
        contentType: 'application/json',
      }})

      axiosInstance.get();
Run Code Online (Sandbox Code Playgroud)

基本上我输入 /get,这会导致 404

在此输入图像描述

在此输入图像描述

在此输入图像描述

然而,当我使用完全相同的场景刷新页面时,它再次以毫秒为单位完成(尽管仍然比 404 慢)

编辑

我创建了一个与我的真实网站几乎相同的托管网站。唯一的区别是这个仅使用 http 而不是 https。

http://52.183.76.195:82/

它不像我的真实网站那么慢,但现在的预检可能需要 40 毫秒,而真正的请求需要 50 毫秒。

我正在最新版本的 Chrome 中测试它,您必须加载网络选项卡并加载/单击按钮(不显示视觉输出)。

在此输入图像描述

Ahm*_*met 2

我不确定您是否使用负载均衡器或其他代理服务,但一个快速修复方法是将 CORS 响应标头移至负载均衡器级别。这将最大限度地减少您的应用程序在任何给定时间可能增加的开销。如何将nginx设置为cors代理服务可以在如何在Nginx代理服务器中启用CORS?