You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular向MVC后端提交注册数据遭CORS拦截,求排查方案

问题描述

我尝试将Angular CLI项目中的注册表单数据发送至MVC后端项目,但现有配置无法解决问题,点击注册按钮时出现CORS拦截错误。以下是已完成的配置:

Angular端注册功能代码

import { Component, OnInit, Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatSnackBar } from '@angular/material';
import { Route, Router } from '@angular/router';
import { MatCardModule } from '@angular/material/card';
import { HttpClient } from '@angular/common/http';
import { analyzeAndValidateNgModules } from '@angular/compiler';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  ngOnInit() {}
  
 data: any;

   constructor(private snackBar:MatSnackBar, private router: Router, private http:HttpClient){}

   onSubmitRegistration(users: {rEmail: string, rPassword: string, rRepeatPassword: string}){
      console.log(users);

          this.http.post('http://localhost:54111/RegisterController', users, {withCredentials: true}).subscribe(data => {
            console.log(data);
  })
      
   }

   login() {
    //login code
   }
 }

MVC后端RegisterController代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Web.Http.Cors;
using static ServerSide.Controllers.RegisterController;

namespace ServerSide.Controllers
{
    [Route("Register")]
    public class RegisterController : ApiController
    {
        string emailRegister;

        public class Data
        {
            public string email { get; set; }
            public string password { get; set; }
            public string repeatPass { get; set; }
        }

        [HttpPost, AllowCrossSite]
         [EnableCors(origins: "http://localhost:4200/login", headers: "*", methods: "*")]
        [Route("api/Register/Posthdf")]
        public IHttpActionResult Posthdf([FromBody] string data)
        {
            if (!ModelState.IsValid) 
                return BadRequest("Date invalide");

            //emailRegister = d.email;
            System.Diagnostics.Debug.WriteLine("***EmailRegister " + data + "***");
            return Ok("lalala");
        }
    }
}

WebApiConfig.cs配置

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace ServerSide.App_Start
{
    public class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.EnableCors();
          //  config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

自定义AllowCrossSiteAttribute类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace ServerSide.Controllers
{
    public class AllowCrossSiteAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
              filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            //  filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "http://82.76.132.129:4400");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200/login");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:54111/api/Register");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE,PUT");
           // filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "http://127.0.0.1:2000");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Headers", "Authorization");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Credentials", "true");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
            base.OnActionExecuting(filterContext);
        }
    }
}

错误截图

CORS拦截错误截图

请问我遗漏了什么配置或步骤?


解决方案

你的问题集中在路由不匹配、CORS配置冲突/无效、参数接收错误三个核心点,以下是具体修复步骤:

1. 修正Angular请求URL与字段匹配

  • 当前请求地址http://localhost:54111/RegisterController与后端实际路由api/Register/Posthdf不符,修改请求地址:
    this.http.post('http://localhost:54111/api/Register/Posthdf', users, {withCredentials: true})
    
  • Angular传递的字段是rEmail、rPassword、rRepeatPassword,后端Data类字段不匹配,同步修改后端类:
    public class Data
    {
        public string rEmail { get; set; }
        public string rPassword { get; set; }
        public string rRepeatPassword { get; set; }
    }
    

2. 启用WebApi属性路由

你注释了config.MapHttpAttributeRoutes();,导致控制器上的[Route]属性完全失效,取消注释:

public static void Register(HttpConfiguration config)
{
    config.EnableCors();
    config.MapHttpAttributeRoutes(); // 取消注释启用属性路由

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

3. 清理无效CORS配置,统一用WebApi原生配置

核心问题:

  • 自定义AllowCrossSiteAttribute继承自System.Web.Mvc.ActionFilterAttribute,而你的控制器是ApiController(WebApi范畴),这个MVC过滤器不会被触发,完全无效。
  • 多次添加Access-Control-Allow-Origin头,浏览器只会保留最后一个值;且使用withCredentials: true时,不能用*作为允许源。
  • EnableCors与自定义过滤器同时存在会导致头冲突。

修复:

  1. 删除自定义AllowCrossSiteAttribute类,或移除控制器上的[AllowCrossSite]属性。
  2. 修改控制器上的[EnableCors]属性,允许正确的源(仅域名+端口)并支持凭证:
    [EnableCors(origins: "http://localhost:4200", headers: "*", methods: "*", SupportsCredentials = true)]
    
  3. 移除控制器上的[Route("Register")],避免与方法路由冲突。

4. 修正后端参数接收方式

当前用[FromBody] string data接收JSON对象,应改用自定义的Data类:

public IHttpActionResult Posthdf([FromBody] Data data)
{
    if (!ModelState.IsValid) 
        return BadRequest("数据无效");

    System.Diagnostics.Debug.WriteLine("***EmailRegister " + data.rEmail + "***");
    return Ok("注册请求已接收");
}

5. 自动处理OPTIONS预检请求

启用EnableCors后,WebApi会自动处理浏览器发送的OPTIONS预检请求,无需额外配置。

完成以上修改后,重启后端与Angular项目,即可解决CORS错误并正常接收注册数据。


内容的提问来源于stack exchange,提问作者Ionut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 16:01:33