跨域问题详解及前后端解决方案

浏览器同源策略的由来

跨域问题的根本原因在于浏览器实施的同源策略(Same-Origin Policy)。该策略是Web安全的基石,用于限制一个源(origin)的文档或脚本如何与另一个源的资源进行交互。只有当两个URL的协议、域名和端口完全一致时,才被视为同源。

跨域的定义

当请求的URL在协议、域名或端口三者中任意一项与当前页面不一致时,即构成跨域访问。例如:

当前页面URL 请求目标URL 是否跨域 说明
http://example.com/ http://example.com/api 协议、域名、端口均相同
http://example.com/ https://example.com/api 协议不同:HTTP vs HTTPS
http://example.com/ http://api.example.com/ 主域相同但子域不同
http://example.com:8080/ http://example.com:3000/ 端口号不一致

非同源环境下的限制行为

  • 存储访问受限:无法读取或修改其他源的 Cookie、LocalStorage 和 IndexedDB 数据。
  • DOM 操作禁止:JavaScript 不能获取或操作来自不同源页面的 DOM 元素。
  • AJAX 请求受阻:XMLHttpRequest 和 Fetch 默认不允许向非同源地址发起请求。

常见的跨域解决方案

目前主流的解决方式包括 JSONP、CORS(跨域资源共享)、代理服务器等。以下以 ASP.NET Core 为例展示服务端配置方法。

启用 CORS 的步骤

Startup.cs 文件中完成如下设置:

1. 注册 CORS 服务

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("AllowSpecificOrigins", builder =>
        {
            builder
                .WithOrigins(
                    "http://localhost:3000",
                    "http://127.0.0.1:3000",
                    "http://localhost:8080"
                )
                .AllowAnyHeader()
                .AllowAnyMethod()
                .AllowCredentials(); // 允许携带凭据(如Cookie)
        });
    });

    services.AddControllers();
}

2. 使用 CORS 中间件

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

    app.UseRouting();

    // 启用CORS中间件,必须在UseRouting之后,UseEndpoints之前调用
    app.UseCors("AllowSpecificOrigins");

    app.UseAuthorization();

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

此外,也可通过特性(Attribute)方式在控制器或动作上单独启用跨域支持:

[EnableCors("AllowSpecificOrigins")]
[ApiController]
[Route("[controller]")]
public class DataController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new { message = "跨域请求成功" });
    }
}

其他可选方案简述

  • JSONP:利用 <script> 标签不受同源策略影响的特点,仅支持 GET 请求,已逐渐被 CORS 取代。
  • Nginx 反向代理:将前端和后端统一通过同一域名暴露,避免跨域问题。
  • Vite/Webpack DevServer 代理:开发环境中通过本地开发服务器转发API请求。

Thẻ: CORS ASP.NET Core 跨域 同源策略 REST API

Đăng vào ngày 16 tháng 05 lúc 16:45