浏览器同源策略的由来
跨域问题的根本原因在于浏览器实施的同源策略(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请求。