У меня возникли проблемы с тем, что React использует мой веб-API. Я получаю следующую ошибку при отправке запроса POST:
Access to XMLHttpRequest at 'https://localhost:7078/api/v1/Authentication/token' from origin 'http://localhost:3000' 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, похоже, настроен. Я следовал инструкциям здесь: https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-7.0:
Программа.cs
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using WatchDog;
using AspNetCoreRateLimit;
using PetTracker.StartupConfig;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Microsoft.OpenApi.Models;
using PetTracker.HealthChecks;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.AddServices();
builder.Services.AddCors(opts =>
{
opts.AddDefaultPolicy(policy =>
{
policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
var app = builder.Build();
app.UseWatchDogExceptionLogger();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(opts =>
{
opts.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
});
}
app.UseHttpsRedirection();
app.MapControllers();
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
app.MapHealthChecksUI();
app.UseWatchDog(opts =>
{
opts.WatchPageUsername = app.Configuration.GetValue<string>("WatchDog:Username");
opts.WatchPagePassword = app.Configuration.GetValue<string>("WatchDog:Password");
opts.Blacklist = "health";
});
app.UseResponseCaching();
app.UseRouting();
app.UseCors();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseIpRateLimiting();
app.Run();
Логин.js
import Button from "react-bootstrap/Button";
import Modal from "react-bootstrap/Modal";
import Form from "react-bootstrap/Form";
import { useState } from "react";
import axios from "axios";
function LoginModal(props) {
const [userName, handleUserName] = useState("");
const [password, handlePassword] = useState("");
async function handleSubmit(e) {
e.preventDefault();
try {
const response = await axios.post(
"https://localhost:7078/api/v1/Authentication/token",
JSON.stringify({ userName, password }),
{
headers: {
"Content-type": "application/json",
},
}
);
console.info(JSON.stringify(response));
} catch (err) {}
}
return (
//Modal
);
}
export default LoginModal;
Я должен что-то упустить. Любая помощь приветствуется
Похоже, ваш интерфейс работает с «http://localhost:3000», а ваш сервер — с «https://localhost:7078». Из-за разных портов это два разных источника, поэтому CORS запрещает доступ к localhost: 7078 с localhost: 3000, и вам нужно либо отключить cors в режиме разработки, либо явно разрешить доступ с localhost: 3000 в вашем бэкэнде, что-то вроде:
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://localhost:3000");
});
});
Или вы также можете настроить сервер разработки webpack (или что-то еще, что вы используете для разработки) для проксирования запросов с localhost: 3000 на localhost: 7078 и изменить свой интерфейс, чтобы он вызывал localhost: 3000, но веб-сервер webpack будет проксировать такие запросы на ваш бэкэнд на localhost: 3000 (и в среде выпуска вы можете сделать то же самое с реальным веб-сервером, таким как nginx или что-то еще, что вы используете)
Я смог понять это. Мое приложение работало в режиме разработки, поэтому мне нужно было добавить app.UseCors(); в этот оператор if в Program.cs:
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(opts =>
{
opts.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
});
app.UseCors();
}
Используя инструменты разработки браузера, вы можете увидеть предварительный запрос? Если это так, возможно, стоит показать детали этого запроса/ответа в вашем вопросе. Кроме того, предположительно при отладке, вы можете увидеть информацию, связанную с CORS, в окне вывода отладки. Если да, то добавьте и это.