Next.js对接ASP.NET API的CORS授权请求问题排查
解决ASP.NET API与Next.js跨域CORS错误问题
问题描述
从Next.js(http://localhost:3000)向ASP.NET API(https://localhost:5001)发起POST请求时,触发以下CORS错误:
Access to XMLHttpRequest at 'https://localhost:5001/api/AdayHesabim/GetAllAdayOnYazi/2' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
Postman请求该API可正常返回结果。
现有后端配置(Startup.cs)
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddTransient<IValidator<Aday>, AdayProfilValidator>(); services.AddCors(options => { options.AddPolicy("AllowAnyOrigin", builder => { builder.WithOrigins("https://localhost:3000"); builder.WithHeaders("content-type"); builder.AllowAnyMethod(); builder.AllowCredentials(); }); }); services.AddScoped<DbContext, SqlDbContext>(); services.AddScoped<ITransactionManager, TransactionScopeManager>(); // JWT authentication配置 string securityKey = "**********"; var key = Encoding.ASCII.GetBytes(securityKey); services.AddAuthentication(x => { ... }) .AddJwtBearer(x => { ... }); services.AddScoped<IAdayHesabimService, AdayHesabimManager>(); ... } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors("AllowAnyOrigin"); app.UseAuthentication(); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
尝试过的CORS策略
options.AddPolicy("AllowAnyOrigin", builder => { builder.AllowAnyOrigin(); builder.AllowAnyHeader(); builder.AllowAnyMethod(); });
Next.js前端请求代码
export const getAdayOnyazilar = async (id,token) => { console.log(`Bearer ${token}, ${id}`); try { const response = await axios.post(`${baseUrl}/AdayHesabim/GetAllAdayOnYazi/${id}`,{ headers:{ Authorization: `Bearer ${token}` } }); return response.data; } catch (error) { if (error.response) { console.log(error.response.data); return error.response.data; } else { console.log("Bir hata oluştu. Lütfen tekrar deneyin. " + error); return "Bir hata oluştu. Lütfen tekrar deneyin. " + error; } } };
解决方案
1. 修正前端axios请求参数顺序
axios.post的参数顺序为url, 请求体, 配置项,你之前将headers误放在了请求体位置,导致axios自动添加不符合预期的content-type头,同时触发预请求检查异常。修改后的代码:
export const getAdayOnyazilar = async (id,token) => { console.log(`Bearer ${token}, ${id}`); try { // 无请求体时传空对象,headers放到第三个参数的配置中 const response = await axios.post(`${baseUrl}/AdayHesabim/GetAllAdayOnYazi/${id}`, {}, { headers:{ Authorization: `Bearer ${token}` } }); return response.data; } catch (error) { if (error.response) { console.log(error.response.data); return error.response.data; } else { console.log("Bir hata oluştu. Lütfen tekrar deneyin. " + error); return "Bir hata oluştu. Lütfen tekrar deneyin. " + error; } } };
2. 修正后端CORS配置的Origin地址
你的Next.js运行在http://localhost:3000,但原配置中写的是https://localhost:3000,导致Origin不匹配,CORS策略失效。同时需要明确允许Authorization头:
services.AddCors(options => { options.AddPolicy("AllowAnyOrigin", builder => { builder.WithOrigins("http://localhost:3000") .AllowAnyHeader() // 允许所有请求头(包括Authorization、Content-Type) .AllowAnyMethod() .AllowCredentials(); }); });
3. 调整中间件顺序
CORS中间件必须放在UseRouting之后,UseAuthentication/UseAuthorization之前,才能正确处理路由相关的CORS检查:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseCors("AllowAnyOrigin"); // 调整到此处 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
4. 给API控制器添加CORS特性
确保CORS策略应用到目标控制器:
[ApiController] [Route("api/[controller]")] [EnableCors("AllowAnyOrigin")] public class AdayHesabimController : ControllerBase { [HttpPost("GetAllAdayOnYazi/{id}")] public IActionResult GetAllAdayOnYazi(int id) { // 业务逻辑 } }
内容的提问来源于stack exchange,提问作者Yusuf Kenan Turak
相关产品推荐
相关产品推荐

