解决 .NET Core 和 nginx 双重配置 CORS 问题

解决 .NET Core 和 nginx 双重配置 CORS 问题

在开发基于 .NET Core 的 Web 应用时,经常会遇到跨域资源共享(CORS)的问题。跨域请求是指浏览器从一个不同的域、协议或端口访问资源。在现代 Web 开发中,跨域请求非常常见,但为了安全,浏览器会阻止这些请求,除非服务器明确允许。

最近在配置 .NET Core 应用与 nginx 服务器时,遇到了一个棘手的 CORS 问题。虽然我们已经在 .NET Core 和 nginx 中配置了 CORS,但浏览器仍然提示跨域请求被阻止。本文将详细介绍问题的原因及其解决方案。

问题描述

我们在 .NET Core 应用和 nginx 服务器中都配置了 CORS,但浏览器仍然报错:Access-Control-Allow-Origin 头部包含多个值,且只允许一个值。

具体的报错信息如下:

Access to XMLHttpRequest at 'http://IP1:8090/api/login/loginPwd' from origin 'http://localhost:5173' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:5173,*', but only one is allowed.

通过检查响应头信息,我们发现响应头中确实存在多次设置 Access-Control-Allow-Origin 的情况:

Access-Control-Allow-Origin: http://IP2:5173
Access-Control-Allow-Origin: *

问题分析

nginx 和 .NET Core 同时配置了 CORS,导致返回的响应头中包含多个 Access-Control-Allow-Origin 头部。这种情况违反了 CORS 规范,浏览器会认为这是一个安全风险,从而阻止请求。

解决方案

为了解决这个问题,我们需要确保 CORS 配置只在一个地方进行。可以选择在 nginx 或 .NET Core 中配置 CORS,但不能同时在两者中配置。

方案 1:在 nginx 中处理 CORS 配置

如果选择在 nginx 中处理 CORS 配置,需要确保 .NET Core 应用不再设置 CORS 头信息。

nginx 配置示例:

server {
    listen 8090;
    location / {
        proxy_pass http://test;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 设置 CORS 头信息
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods *;
        add_header Access-Control-Allow-Headers *;
        add_header Access-Control-Allow-Credentials true;

    }
}
方案 2:在 .NET Core 中处理 CORS 配置

如果选择在 .NET Core 中处理 CORS 配置,需要确保 nginx 不再设置 CORS 头信息。

nginx 配置示例:

server {
    listen 8090;
    location / {
        proxy_pass http://test;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 不设置 CORS 头信息
        # 删除以下行或注释掉
        # add_header Access-Control-Allow-Origin "*";
        # add_header Access-Control-Allow-Methods "*";
        # add_header Access-Control-Allow-Headers "*";
        # add_header Access-Control-Allow-Credentials true;
    }
}

.NET Core 配置示例:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("AllowSpecificOrigin",
            builder =>
            {
                builder.WithOrigins("*")
                       .AllowAnyHeader()
                       .AllowAnyMethod()
                       .AllowCredentials();
            });
    });

    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseCors("AllowSpecificOrigin");

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

总结

在处理跨域请求时,确保 CORS 配置只在一个地方设置,以避免配置冲突。通过选择在 nginx 或 .NET Core 中配置 CORS,可以解决跨域请求被阻止的问题。在实际开发中,选择合适的配置方案,以满足项目的具体需求和架构设计。希望本文能帮助大家解决类似的 CORS 问题,让跨域请求更加顺畅。

posted @ 2024-07-04 15:43  p1016520  阅读(3)  评论(0编辑  收藏  举报