当前位置: 首页 > news >正文

服务器跨域问题CORS的解决

制作大屏过程中,通过API连接服务器,出现如下错误:

Access to XMLHttpRequest at ‘http://192.168.88.74:8089/Service/data/-3005?name=API’ from origin ‘http://localhost:3020’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

原因分析

这个错误是由于浏览器的 CORS(跨域资源共享)安全机制导致的。当你的前端应用(运行在http://localhost:3020)尝试访问不同源的后端 API(http://192.168.88.74:8089)时,浏览器会进行 CORS 检查。
要解决这个问题,需要在后端服务器的响应中添加适当的 CORS 头信息。具体来说,需要添加Access-Control-Allow-Origin头,指定允许访问的源。

处理过程

在 .NET 后端中添加 CORS 头,如果是传统的 ASP.NET 项目,可以在 Global.asax 中配置:

protected void Application_BeginRequest()
{// 允许的源(生产环境建议指定具体域名,不要用*)Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:3020");// 允许的请求方法Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");// 允许的请求头Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization");// 处理预检请求if (Request.HttpMethod == "OPTIONS"){Response.StatusCode = 200;Response.End();}
}

1 Response.Headers.Add后两句是否可以不要

这两句是否可以省略,取决于前端跨域请求的具体场景。如果前端只发送简单的 GET 请求(不包含自定义头信息、不携带凭据等),那么这两句可以省略。因为简单请求不会触发预检请求(OPTIONS),浏览器只会检查Access-Control-Allow-Origin头,只要这个头配置正确,简单请求就能正常工作。

如果前端有以下场景,必须保留这两句:

  • 使用 POST/PUT/DELETE 等非 GET 方法
  • 请求中包含自定义头信息(如 Authorization、Token 等)
  • 发送 JSON 格式的 POST 请求(Content-Type: application/json)

这些情况会触发浏览器发送预检请求(OPTIONS),此时浏览器会检查:

  • 服务器是否允许对应的请求方法(通过Access-Control-Allow-Methods)
  • 服务器是否允许对应的请求头(通过Access-Control-Allow-Headers)

如果缺少这两个头,预检请求会失败,浏览器会阻断实际的业务请求。因此,即使当前只使用简单的 GET 请求,也建议保留这两句,因为:

  • 未来可能会扩展使用其他请求方法或头信息
  • 明确配置可以避免后续开发中出现意外的 CORS 错误
  • 这两句配置对简单请求没有负面影响

所以最好的实践是保留这两个头的配置,确保兼容各种跨域请求场景。

2 预检请求是什么(OPTIONS 请求)

当浏览器判断一个跨域请求是 “复杂请求” 时(比如包含自定义头信息、使用 PUT/DELETE 等 HTTP 方法),会在真正发送请求之前,先发送一个OPTIONS 方法的预检请求,用来询问:

  1. 询问服务器是否允许当前源的跨域请求
  2. 询问服务器支持哪些 HTTP 方法和请求头

只有当服务器正确响应并允许后,浏览器才会发送真正的业务请求(比如 GET/POST)。

代码中if (Request.HttpMethod == “OPTIONS”)的逻辑是:

  • 如果检测到是预检请求(OPTIONS 方法)
  • 直接返回 200 状态码(表示允许)
  • 不需要返回业务数据,直接结束响应

这样浏览器就会认为 “服务器允许跨域”,进而发送真正的业务请求。如果没有这段处理,服务器可能会对 OPTIONS 请求返回 404 或其他错误状态,导致浏览器阻断后续的实际请求,从而出现 CORS 错误。

3 AllowedCorsHeaders是否只是针对跨域的进行限制

确实是专门针对跨域请求的请求头限制,它的作用是告诉浏览器:“服务器允许前端跨域请求中携带哪些自定义头信息”。

  1. 它只限制跨域请求中前端携带的头信息,对同域请求(前端和后端在同一域名 / 端口)没有任何影响。
  2. 不需要也不应该添加所有可能的头,而是按需添加。如果开发阶段不确定需要哪些头,或头信息频繁变化,可临时用通配符允许所有头(不推荐生产环境):
Response.Headers.Add("Access-Control-Allow-Headers", "*")
  1. 如果缺少必要的头配置,会出现类似以下错误, 此时只需将 X-Token 添加到 AllowedCorsHeaders 即可解决。
Request header field X-Token is not allowed by Access-Control-Allow-Headers in preflight response.

解决办法

最终的解决办法是在 .NET 项目中实现跨域源的动态化,核心是避免将域名硬编码在代码里。

  1. 第一步:在 web.config 中添加跨域源配置

在 < appSettings > 节点下新增配置项,支持多个源(用英文逗号分隔):

<configuration><appSettings><!-- 动态配置允许的跨域源,多个源用逗号分隔 --><add key="AllowedCorsOrigins" value="http://localhost:3020,http://test.example.com,http://prod.example.com" /><!-- 可选:配置允许的请求方法和头 --><add key="AllowedCorsMethods" value="GET,POST,PUT,DELETE,OPTIONS" /><add key="AllowedCorsHeaders" value="Content-Type,Authorization" /></appSettings>
</configuration>
  1. 第二步:在 Global.asax 中读取配置并应用
using System.Configuration; // 需引用 System.Configuration 程序集protected void Application_BeginRequest()
{// 1. 读取配置的跨域源(支持多个)string allowedOrigins = ConfigurationManager.AppSettings["AllowedCorsOrigins"];// 2. 读取当前请求的源(前端页面的域名)string requestOrigin = Request.Headers.Get("Origin");// 3. 验证当前请求源是否在允许列表中(避免直接返回 *,支持多源)if (!string.IsNullOrEmpty(allowedOrigins) && !string.IsNullOrEmpty(requestOrigin)){var originList = allowedOrigins.Split(',');if (originList.Contains(requestOrigin)){// 动态添加允许的源Response.Headers.Add("Access-Control-Allow-Origin", requestOrigin);// 动态添加允许的方法(从配置读取)Response.Headers.Add("Access-Control-Allow-Methods", ConfigurationManager.AppSettings["AllowedCorsMethods"]);// 动态添加允许的头(从配置读取)Response.Headers.Add("Access-Control-Allow-Headers", ConfigurationManager.AppSettings["AllowedCorsHeaders"]);// 支持凭据(如 Cookie,可选)Response.Headers.Add("Access-Control-Allow-Credentials", "true");}}// 4. 处理预检请求(OPTIONS)if (Request.HttpMethod == "OPTIONS"){Response.StatusCode = 200;Response.End();}
}
http://www.dtcms.com/a/406934.html

相关文章:

  • MyBatis进行级联查询
  • MySQL8.0.26-Linux版安装
  • 济南网站建设_美叶网络网址域名查询
  • 深入了解linux网络—— UDP网络通信
  • 招商加盟的网站应该怎么做宝坻做网站哪家好
  • 视频网站开发工具网站备案中是什么意思
  • 物理媒介和分组交换原理
  • Linux常用命令53——file
  • 西双版纳 网站建设网络建设与运维初级
  • 【Python】文件处理(一)
  • win10怎么做网站wordpress wooyun
  • 织梦网站登录网上做网站赚钱吗
  • Linux数据安全与备份策略完全指南
  • 哈尔滨网站建设服务公司暴雪游戏服务中心
  • wordpress 关闭评论网站优化排名提升
  • 硅基计划5.0 MySQL 壹 初识MySQL 初版
  • Linux之挂载新的硬盘(超详细!)
  • 部署 GitLab 服务器
  • C++项目:仿muduo库高并发服务器-------connection模块
  • 网站建设需要的资质互联网保险的发展现状
  • 8-机器学习与大模型开发数学教程-第0章 预备知识-0-8 编程与数值计算基础(浮点数精度、溢出、数值稳定性)
  • php网站开发书微信公众号手机网站开发
  • 做网站需要工商执照吗代人做网站
  • Go基础:模块化管理为什么能够提升研发效能?
  • 合肥专业做网站公司wd wordpress
  • IR 680LT Maleimide,IR 680LT马来酰亚胺用于蛋白质标记与定量分析
  • 打工人日报#20250925
  • Kubernetes Pod 的生命周期与故障排查
  • Java List列表创建方法大总结
  • 河南工信建设网站市场营销师报名官网