Because real-time messages are needed in the project, ASP.NET(Core) SignalR real-time communication library is used. Because business services and communication services are independent, cross domain issues are involved. The exceptions thrown by the browser are very obvious. This is obviously cross domain related content. The error information is as follows:
Access to XMLHttpRequest at 'http://192.168.2.13:5005/api/v1/commommessage/messageHub/negotiate' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORS (cross domain resource sharing) is a W3C standard that allows servers to relax the homology policy. With CORS, the server can reject other cross domain requests when it explicitly allows some cross domain requests. CORS is more secure and flexible than other cross domain technologies (such as JSONP).
The cross domain problem of ASP.NET Core needs to be configured in the StartUp.cs file.
Add content to ConfigureServices method
services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.AllowAnyMethod() .AllowAnyHeader() .AllowAnyOrigin() .AllowCredentials(); }));
The complete ConfigureServices method example is as follows:
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.AllowAnyMethod() .AllowAnyHeader() .AllowAnyOrigin() .AllowCredentials(); })); services.AddMvc(options => { options.Filters.Add(); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) //Global configuration Json serialization processing .AddJsonOptions(options => { options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }) .AddFluentValidation(); services.AddSignalR(); return services.AutofacServiceProvider(); }
Add in the Configure method
app.UseCors("CorsPolicy");
Example of a complete Configure method:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IOptions config) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } if (env.IsProduction()) { //Register service to consumer app.UseConsul(); using (HttpClient client = new HttpClient()) { StringContent content = new StringContent(JsonConvert.SerializeObject(config.Value.RegisterParams)); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); HttpResponseMessage message = client.PostAsync(config.Value.Server.Address, content).Result; }; } app.UseCors("CorsPolicy"); loggerFactory.AddNLog(); env.ConfigureNLog("nlog.config");//Read Nlog configuration file app.UseSignalR(routes => { routes.MapHub("/api/v1/examinations/messageHub"); }); app.UseMvc(); }
Special note: app.UseCors() must be placed before app.UseMvc().
I thought it was over, but I never thought it was still useless. The browser console error still exists, and the. net core also prompts relevant warnings. I almost forgot to use the. net core version now, which is different from before.
The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the policy by listing individual origins if credentials needs to be supported.
At present, ASP.NET CORE 2.1 is used, and its Cors components have been upgraded. For security reasons, the content to be allowed must be specified. It's part of security. You can't do that. Access control allow origin cannot use * if credentials are to be allowed. You must specify the exact protocol + domain + port.
In fact, this problem is also very easy to solve. You only need to give a trusted list. The amendments are as follows:
services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.WithOrigins(new string[] { "http://127.0.0.1:5500" }) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }));
If you really don't want to make any restrictions, there are ways. You only need to replace AllowAnyOrigin with setisoriginallowed (= > true).
services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.AllowAnyMethod() .SetIsOriginAllowed(_ => true) .AllowAnyHeader() .AllowCredentials(); }));
In addition to the above two methods, you can also customize the middleware. Add Cors processing class. As follows:
public class CorsMiddleware { private readonly RequestDelegate next; public CorsMiddleware(RequestDelegate next) { this.next = next; } public async Task Invoke(HttpContext context) { if (context.Request.Headers.ContainsKey(CorsConstants.Origin)) { context.Response.Headers.Add("Access-Control-Allow-Origin", context.Request.Headers["Origin"]); context.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH"); context.Response.Headers.Add("Access-Control-Allow-Headers", context.Request.Headers["Access-Control-Request-Headers"]); context.Response.Headers.Add("Access-Control-Allow-Credentials", "true"); if (context.Request.Method.Equals("OPTIONS")) { context.Response.StatusCode = StatusCodes.Status200OK; return; } } await next(context); } }
Add the following content to the Configure method
app.UseMiddleware<CorsMiddleware>();