跨域请求预检响应返回405错误,Angular2+C#后端如何解决?
我之前帮好几个开发者解决过一模一样的问题,你遇到的是跨域预检请求(OPTIONS)被服务器拒绝的典型情况,咱们一步步来排查修复:
第一步:确认WebAPI CORS包已正确安装
首先得确保你已经安装了官方的CORS NuGet包,很多人漏了这一步导致config.EnableCors()无效。打开NuGet包管理器,安装Microsoft.AspNet.WebApi.Cors,或者在Package Manager Console里执行:
Install-Package Microsoft.AspNet.WebApi.Cors
第二步:正确配置WebApiConfig的全局CORS
光加config.EnableCors()还不够,得指定允许的域名、头和方法。打开WebApiConfig.cs,修改Register方法:
public static void Register(HttpConfiguration config) { // 全局配置CORS,生产环境请替换*为你的前端域名(比如http://localhost:4200) var corsSettings = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(corsSettings); // 保留你原有的路由配置 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); }
注意:如果只想给特定控制器启用CORS,可以在控制器类上加上[EnableCors(origins: "*", headers: "*", methods: "*")]属性,全局和局部选一种就行,不要重复配置。
第三步:配置web.config让IIS正确处理OPTIONS请求
IIS默认可能会拦截OPTIONS请求,导致返回405。在web.config的<system.webServer>节点里添加以下配置:
<system.webServer> <handlers> <!-- 移除默认的OPTIONS处理器,添加自定义的允许所有OPTIONS请求 --> <remove name="OPTIONSVerbHandler" /> <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" resourceType="Unspecified" requireAccess="None" /> </handlers> <httpProtocol> <customHeaders> <!-- 这些头会在预检响应里返回,确保和WebApiConfig的配置一致 --> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type, Accept, Authorization" /> <!-- 如果有自定义头要加上 --> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /> </customHeaders> </httpProtocol> </system.webServer>
第四步:确保控制器能响应OPTIONS请求
有些时候,即使配置了CORS,控制器没有处理OPTIONS方法的动作,还是会返回405。你可以创建一个基类控制器,让所有API控制器继承它:
public class BaseApiController : ApiController { // 处理OPTIONS预检请求 public HttpResponseMessage Options() { return new HttpResponseMessage(HttpStatusCode.OK); } }
然后你的API控制器改成:
public class YourController : BaseApiController { // 你的POST方法 [HttpPost] public IHttpActionResult PostData(YourModel model) { // 业务逻辑 return Ok(); } }
第五步:检查前端请求的自定义头
如果你的Angular请求带了自定义头(比如Authorization),一定要在Access-Control-Allow-Headers里包含这些头,否则预检会失败。比如Angular里的请求:
const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': 'Bearer your-token' }); this.http.post('http://your-api-url', data, { headers: headers }).subscribe(...);
那web.config里的Access-Control-Allow-Headers就要加上Authorization。
按以上步骤走下来,应该就能解决OPTIONS预检405的问题了。如果还是不行,可以检查浏览器控制台的Network面板,看看预检请求的响应头里有没有正确返回Access-Control相关的字段,或者有没有其他错误信息。
内容的提问来源于stack exchange,提问作者Svibhor

