我已启用 CORS,如下
程序.cs
builder.Services.AddCors();
var app = builder.Build();
app.UseRouting();
app.UseCors(x => x.AllowAnyMethod().AllowAnyHeader().AllowCredentials().SetIsOriginAllowed(origin => true));
app.UseAuthentication();
客户
const axiosClient = axios.create({
baseURL: configuration.apiUrl,
headers: { "Content-type": "application/json" },
withCredentials: true });
服务器(LaunchSettings.json)
"CustomProfile": {
"commandName": "IISExpress",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
}
},
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:60737",
"sslPort": 44358
}
}
当我打电话时
// Get records list
axiosClient.get('records').then((res: AxiosResponse) => res.data)
我收到带有数据的状态代码 200,并且用户已在后端进行身份验证。
但是当我打电话时
// Create new record
axiosClient.post('record', createCommand).then((res: AxiosResponse) => res.data)
我收到以下错误消息
从“https://localhost:44358/api/records”访问 XMLHttpRequest 来源 'https://localhost:44414' 已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。
知道可能出了什么问题以及如何解决它吗?
您在服务器端的 CORS 设置似乎基本正确,允许任何来源和凭据。但是,预检请求(当您发出“非简单”请求时,浏览器会自动发送该请求,例如带有 JSON 正文的
POST
请求)似乎失败了。
Access-Control-Allow-Origin
标头未在预检响应中发送,这是允许来自不同来源的实际请求所必需的。
预检请求是匿名的,因此 Windows 身份验证只会阻止所有请求并导致问题。您必须在 IIS 或 IIS Express 上使用 IIS CORS 模块才能正确处理该问题。
您可以在“如何使用 Windows 身份验证在 IIS 上授权 CORS 预检请求”中看到该建议,使用 CORS 模块。
您需要通过 Webconfig 启用 CORS 模块:
<configuration>
<system.webServer>
<cors enabled="true">
<add origin="https://localhost:44414" allowCredentials="true">
<allowHeaders allowAllRequestedHeaders="true"/>
<allowMethods>
<add method="GET"/>
<add method="POST"/>
<add method="OPTIONS"/>
</allowMethods>
</add>
</cors>
</system.webServer>
</configuration>
ASP.NET Core 中中间件的顺序会影响它们的行为。并指定允许的来源,而不是允许任何来源。这是防止潜在安全问题的良好做法。
将您的 CORS 设置更改为:
var app = builder.Build();
app.UseCors(x => x
.WithOrigins("https://localhost:44414")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseRouting();
app.UseAuthentication();
使用浏览器开发人员工具,检查预检(选项)请求和响应,以查看发送和接收的标头。确保响应中包含
Access-Control-Allow-Origin
标头并具有正确的值。
当我添加 web.config 文件时,CORS 元素突出显示为无效,并且网站抛出 HTTP 错误 500.19 - 内部服务器错误。
如果 IIS Express 不支持 CORS 模块,则只能在完整版 IIS 中配置。这可能就是您在尝试将 CORS 配置添加到
web.config
文件时遇到 HTTP 错误 500.19 的原因。但鉴于此限制,我们可能需要恢复直接在 ASP.NET Core 应用程序中配置 CORS,您已经在
Program.cs
文件中开始执行此操作。确保
Program.cs
中的中间件订购正确。 UseCors
方法应位于 UseAuthentication
和 UseAuthorization
方法之前。
var app = builder.Build();
app.UseCors(x => x
.WithOrigins("https://localhost:44414")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
考虑到 IIS Express 和 Windows 身份验证的限制,您可能需要在 ASP.NET Core 应用程序中手动处理预检请求。这涉及创建一个中间件来拦截 OPTIONS 请求并在应用 Windows 身份验证之前返回 200 OK 响应。
您可以像这样创建一个中间件:
app.Use((context, next) =>
{
if (context.Request.Method.Equals("OPTIONS", StringComparison.InvariantCultureIgnoreCase))
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
return Task.CompletedTask;
}
return next();
});
将此中间件放在中间件管道的最开始,甚至在
UseCors
中间件之前。
实施这些更改后,通过 Visual Studio 在调试模式下运行应用程序来测试您的设置,并尝试从客户端应用程序发出 OPTIONS、GET 和 POST 请求以验证问题是否已解决。 (不要忘记清除浏览器的缓存或尝试在隐身/私人窗口中以避免测试时出现任何缓存问题。)
通过专注于在 ASP.NET Core 应用程序中正确配置 CORS 并确保预检请求能够成功绕过 Windows 身份验证,您应该能够通过 Visual Studio 使用 IIS Express 开发在您的开发环境中工作的解决方案。