React对接.NET后端CORS配置无效及数据提交失败求助
问题求助:React注册组件CORS错误+数据无法写入数据库
问题现象
- React注册页面提交时触发CORS错误,尝试多种CORS配置、axios/原生请求方式均无效
- 点击提交后,填写的用户数据未写入数据库
React注册组件代码
import axios from 'axios'; import { useState } from 'react'; const Registration = () => { const [formData, setFormData] = useState({ userName: '', userEmail: '', userPhoneNumber: '', userAddress: '', userAge: 0, userGender: '', role: '' }); const [error, setError] = useState(null); const handleChange = (e) => { const { name, value } = e.target; setFormData({ ...formData, [name]: name === 'userAge' ? Number(value) : value, }); }; const handleSubmit = async (e) => { e.preventDefault(); try { const response = await axios.post('https://localhost:7094/api/User/Create', formData); console.log('Response data:', response.data); // 可在此处添加登录跳转或成功提示逻辑 } catch (error) { console.error('请求失败:', error); setError(error.response?.data?.message || error.message); } }; return ( <form onSubmit={handleSubmit}> {error && <div style={{ color: 'red' }}>{error}</div>} <div> <label>UserName:</label> <input type="text" name="userName" value={formData.userName} onChange={handleChange} required /> </div> <div> <label>Email:</label> <input type="email" name="userEmail" value={formData.userEmail} onChange={handleChange} required /> </div> <div> <label>Phone Number:</label> <input type="text" name="userPhoneNumber" value={formData.userPhoneNumber} onChange={handleChange} /> </div> <div> <label>Address:</label> <input type="text" name="userAddress" value={formData.userAddress} onChange={handleChange} /> </div> <div> <label>Age:</label> <input type="number" name="userAge" value={formData.userAge} onChange={handleChange} /> </div> <div> <label>Gender:</label> <input type="text" name="userGender" value={formData.userGender} onChange={handleChange} /> </div> <div> <label>Role (用户或管理员):</label> <input type="text" name="role" value={formData.role} onChange={handleChange} required /> </div> <button type="submit">Submit</button> </form> ); }; export default Registration;
页面错误信息

.NET后端Program.cs代码
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using System.Text; using TrainTicket.Interfaces; using TrainTicket.Models; using TrainTicket.Repository; var builder = WebApplication.CreateBuilder(args); var corsOrigins = new string[] { "http://localhost:5173" }; builder.Services.AddCors(options => { options.AddPolicy("AllowAll", policy => { policy.WithOrigins(corsOrigins) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); }); builder.Services.AddControllers(); builder.Services.AddHttpContextAccessor(); builder.Services.AddAutoMapper(typeof(Program)); builder.Services.AddDbContext<ReservationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddScoped<IUserLoginInterface, UserLoginRepository>(); builder.Services.AddScoped<IUserInterface, UserRepository>(); builder.Services.AddScoped<IAdminLoginInterface, AdminLoginRepository>(); builder.Services.AddScoped<ITrainDetailsInterface, TrainDetailsRepository>(); builder.Services.AddScoped<ISeatDetailsInterface, SeatDetailsRepository>(); builder.Services.AddScoped<ISearchDetailsInterface, SearchDetailsRepository>(); builder.Services.AddScoped<IEmailSenderInterface, EmailSenderRepository>(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])), ClockSkew = TimeSpan.Zero }; }); builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new() { Title = "TrainTicket API", Version = "v1" }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme", Type = SecuritySchemeType.Http, Scheme = "bearer" }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, Array.Empty<string>() } }); }); var app = builder.Build(); app.UseCors("AllowAll"); app.UseAuthentication(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TrainTicket API v1")); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
核心需求
注册页面收集userName、userEmail、PhoneNumber、Address、Age、Gender、Role(用户/管理员),userId和密码自动生成,提交后数据需写入数据库。
解决方案
1. 修复React组件基础问题
- 补全
useState导入:原代码未导入React核心Hook,导致组件无法正常渲染 - 添加
role字段:原formData未包含role属性,导致前端输入的角色无法传递到后端 - 修正axios请求处理:axios返回的
response已自动解析JSON,无需额外调用response.json() - 类型转换处理:将
userAge从字符串转为数字,避免后端类型不匹配
2. 解决CORS问题
当前配置逻辑正确,需排查以下点:
- 确认前端端口:确保前端运行在
http://localhost:5173,若端口不符则修改corsOrigins数组 - 简化CORS配置:若前端未发送Cookie,可移除
.AllowCredentials(),减少校验复杂度 - 中间件顺序:确保
UseCors在UseAuthorization和UseHttpsRedirection之前(当前顺序已符合要求) - 直接测试API:用Postman调用
https://localhost:7094/api/User/Create,确认接口本身可正常写入数据
3. 后端接口关键修复
- 允许匿名访问注册接口:注册接口无需JWT认证,需添加
[AllowAnonymous]特性,避免被认证拦截[ApiController] [Route("api/[controller]")] public class UserController : ControllerBase { private readonly IUserInterface _userRepo; public UserController(IUserInterface userRepo) { _userRepo = userRepo; } [HttpPost("Create")] [AllowAnonymous] public async Task<IActionResult> CreateUser(UserDto userDto) { var user = new User { UserName = userDto.UserName, UserEmail = userDto.UserEmail, UserPhoneNumber = userDto.UserPhoneNumber, UserAddress = userDto.UserAddress, UserAge = userDto.UserAge, UserGender = userDto.UserGender, Role = userDto.Role, UserId = Guid.NewGuid().ToString(), Password = GenerateRandomPassword() }; await _userRepo.CreateUser(user); return Ok(new { UserId = user.UserId, Password = user.Password }); } private string GenerateRandomPassword() { var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var random = new Random(); return new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray()); } } - 确认Repository写入逻辑:确保
UserRepository正确执行添加和保存操作public class UserRepository : IUserInterface { private readonly ReservationDbContext _context; public UserRepository(ReservationDbContext context) { _context = context; } public async Task CreateUser(User user) { _context.Users.Add(user); await _context.SaveChangesAsync(); } } - 字段名映射检查:确保前端字段名(如
userName)与后端模型字段名(如UserName)符合ASP.NET Core驼峰命名自动映射规则
4. 调试建议
- 前端调试:查看浏览器Network面板,检查请求状态码、请求头、请求体是否正确
- 后端调试:在
CreateUser方法设置断点,确认是否接收到前端数据,写入过程是否有异常 - 日志排查:添加后端日志记录请求细节和错误信息,快速定位问题
内容的提问来源于stack exchange,提问作者whizzx
相关产品推荐
相关产品推荐

