[英].net core api CORS Get works but cors gets 405
我有以下中间件:
namespace TimeManagement
{
public class CorsMiddleware
{
private readonly RequestDelegate _next;
public CorsMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext)
{
httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
httpContext.Response.Headers.Add("Access-Control-Allow-Headers",
"Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
return _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<CorsMiddleware>();
}
}
}
以及以下startup
类:
namespace TimeManagement
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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.AddDbContext<WorkTimeContext>(opt =>
opt.UseInMemoryDatabase("WorkTime"));
services.AddDbContext<TimeManagementContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("TimeManagementContext")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseCorsMiddleware();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
}
}
然后我尝试运行https://localhost:5001/api/WorkTimes
GET 并且它返回没有问题。
现在我正在使用Angular
前端,然后我尝试发布。 您可能知道,它首先发送一个OPTIONS
,在这里我收到一个CORS
错误:
您需要为 CORS 预检请求发送状态代码 200,您的中间件现在没有设置。
为什么不直接使用处理此问题的 ASP.NET CORS 中间件? ASP.NET CORS 中间件
在这里 ,
当通过GET HTTP方法请求发送有效凭据时,服务器使用它来返回特定数据集。因此,在这种情况下,服务器在该资源/URL 上接受POST请求是没有意义的,因此它可能发出此类请求时,以405(不允许方法)状态代码响应。
405(Method Not Allowed) 是一个 HTTP 响应状态码,表示指定的请求 HTTP 方法已被服务器接收并识别,但服务器拒绝了请求资源的特定方法。 405 代码响应确认请求的资源有效且存在,但客户端在请求期间使用了不可接受的 HTTP 方法。
这可能发生在几种不同的情况下:
使用下面的 ASP.NET CORS 中间件而不是自定义中间件。(Asp.Net Core v3.0 示例代码)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseCors(cor=> cor
.AllowAnyHeader()
.WithOrigins("http://localhost:4200","https://localhost:4200"));
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
您可以尝试将以下内容放入 web.config 中:
<httpHandlers>
...
<add path="*" verb="OPTIONS" type="System.Web.DefaultHttpHandler" validate="true"/>
</httpHandlers>
铬不支持这一点。
Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
方案一【临时开发方案】
chrome://flags/#out-of-blink-cors
通过将该地址复制并粘贴到 Chrome 的地址栏中,然后按 [enter] 来禁用out-of-blink-cors
标志。 在打开的页面中,您会看到一个突出显示的所谓“标志”(实验)。 禁用它并重新启动 Chrome(编辑:之前我说过要启用该标志,但似乎只有禁用才有效)
在许多情况下可以解决问题。 您可以在此处为chrome 上的此功能点赞
解决方案2(推荐)
在子域下创建您的api
你的 api url 将是http://localhost:4200/api/YourEndpoint
这里
Voyage是我们的角度应用程序。
在它的Api下,我们托管我们的 API,因此它们将位于同一域下,因此不会违反 CORS 政策。
Cors 错误可能非常棘手。 有时浏览器在没有真正调用你的 api 的情况下返回这个错误。 所以第一步你需要确保浏览器调用你的 API。 为此,我通常添加一个愚蠢的内联中间件并在其中放置一个断点。 你也可以给它添加一个记录器。
哑中间件示例:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) =>
{
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
// The others middlewares.
}
现在您知道问题出在您的浏览器还是您的应用程序中,您可以做什么?
1) 如果问题出在您的浏览器中,请按照@Eldho 回答中的说明启用它。
2)如果问题出在您的应用程序中,请阅读我的其余答案。
中间件的执行顺序与您在 Configure 方法中调用的顺序相同。
也许HttpsRedirection
正在返回此错误。 (大也许在这里)
您可以尝试在HttpsRedirection
之前声明您的自定义app.UseCorsMiddleware()
。 但我建议您使用已经存在且运行良好的 Asp.net Cors Middlewares。 为什么要重新发明轮子?
这是Asp.Net Core v2.1 Cors Middleware的示例
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("Any",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("Any");
// The others middlewares.
}
另一种方法(仅用于开发)是使用SPA 中间件转发您的 SPA 请求。 这样,您的 angular 应用程序和 Asp.Net 应用程序将在 localhost 的同一端口上应答,而 chrome 不会阻止任何端口。 但它只是作为临时解决方案。 不建议在生产中使用它。
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("Any");
// The others middlewares.
if (env.IsDevelopment())
{
app.UseSpa(spa =>
{
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.