欢迎光临
我们一直在努力

服务器跨域问题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 方法的预检请求,用来询问:

  • 询问服务器是否允许当前源的跨域请求
  • 询问服务器支持哪些 HTTP 方法和请求头
  • 只有当服务器正确响应并允许后,浏览器才会发送真正的业务请求(比如 GET/POST)。

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

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

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

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

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

  • 它只限制跨域请求中前端携带的头信息,对同域请求(前端和后端在同一域名 / 端口)没有任何影响。
  • 不需要也不应该添加所有可能的头,而是按需添加。如果开发阶段不确定需要哪些头,或头信息频繁变化,可临时用通配符允许所有头(不推荐生产环境):
  • Response.Headers.Add("Access-Control-Allow-Headers", "*")

  • 如果缺少必要的头配置,会出现类似以下错误, 此时只需将 X-Token 添加到 AllowedCorsHeaders 即可解决。
  • Request header field X-Token is not allowed by Access-Control-Allow-Headers in preflight response.

    解决办法

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

  • 第一步:在 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>

  • 第二步:在 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();
    }
    }

    赞(0)
    未经允许不得转载:171主机测评 » 服务器跨域问题CORS的解决
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址