如何解决IIS托管网站间的CORS跨域错误?
核心问题分析
GET请求正常但POST失败,本质是预检OPTIONS请求未通过——浏览器在发送带自定义头或非简单方法的请求前会先发送OPTIONS预检,若服务器未正确响应OPTIONS请求,就会触发CORS错误。本地正常服务器异常,说明服务器环境存在配置差异。
具体排查与修复步骤
1. 修正CORS方法配置的语法错误
你的WithMethods写法存在问题:将所有方法写在一个带逗号和空格的字符串里,.NET会将整个字符串识别为单个方法名,导致OPTIONS方法未被允许。正确写法是将每个方法作为独立参数传入:
services.AddCors(opt => { opt.AddPolicy("CORSPolicy", policy => { policy.AllowAnyHeader() .WithMethods("PUT", "POST", "GET", "DELETE", "PATCH", "OPTIONS") // 每个方法单独传参 .WithOrigins("http://localhost:81", "http://<<ip>>:81"); }); });
2. 确保API端点映射正确
检查服务器上的Program.cs(或Startup.cs)是否添加了端点映射代码,CORS政策需要绑定到API端点才能生效:
// 在UseAuthorization之后添加 app.MapControllers(); // 映射API控制器
如果缺少这行代码,.NET不会处理API请求,预检OPTIONS请求自然无法得到正确响应。
3. 配置IIS允许OPTIONS请求
服务器上的IIS可能会拦截OPTIONS请求,不让其到达.NET后端。在项目的web.config中添加以下配置,确保OPTIONS请求能被正确处理:
<system.webServer> <handlers> <!-- 移除默认的OPTIONS处理器,替换为允许所有OPTIONS请求 --> <remove name="OPTIONSVerbHandler" /> <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" resourceType="Unspecified" requireAccess="None" /> </handlers> <httpProtocol> <!-- 可选:若.NET CORS仍不生效,可临时添加这些头(注意不要和.NET配置冲突) --> <customHeaders> <add name="Access-Control-Allow-Origin" value="http://localhost:81, http://<<ip>>:81" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, PATCH, OPTIONS" /> <add name="Access-Control-Allow-Headers" value="*" /> </customHeaders> </httpProtocol> </system.webServer>
4. 检查请求URL的正确性
错误信息中的请求URL是http://localhost/api/Website/Login,但你的API部署在http://localhost:80/,确认前端调用时是否遗漏了端口号。若服务器上的IIS绑定了域名,要确保前端请求的域名/端口和WithOrigins中配置的一致,且API的URL正确指向80端口的站点。
5. 排查.NET环境与日志
- 确认服务器上的.NET运行时版本和本地一致,不同版本的CORS处理逻辑可能存在差异。
- 启用CORS日志排查:在服务器的
appsettings.json中添加日志配置,查看CORS政策未应用的具体原因:
{ "Logging": { "LogLevel": { "Microsoft.AspNetCore.Cors": "Debug" } } }
部署后查看日志文件,定位具体的CORS拦截原因。
6. 检查IIS CORS模块冲突
若服务器上安装了IIS官方的CORS模块,它会和.NET的CORS配置产生冲突。可以通过IIS管理器禁用该模块,或统一使用IIS的CORS配置替代.NET代码中的配置。
内容的提问来源于stack exchange,提问作者user1285836

