什么是跨域?一文彻底搞懂 CORS 机制

简介: 本文深入解析Web开发中的跨域问题,涵盖同源策略、CORS原理、简单请求与预检请求机制,以及前后端配置方法,帮助开发者理解并解决常见的CORS错误,安全实现跨域资源共享。

在 Web 开发中,你是否遇到过这样的错误?

“Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy.”

这就是典型的跨域问题。本文将带你从根源理解:

  • 什么是跨域?
  • 为什么浏览器要限制跨域?
  • CORS 是如何解决这个问题的?
  • 前后端如何正确配置 CORS?

一、什么是“同源”?什么是“跨域”?

✅ 同源策略(Same-Origin Policy)

这是浏览器的一项安全机制:  

只有协议(protocol)、域名(host)、端口(port)完全相同的两个页面,才被认为是“同源”的,可以互相访问资源。

URL A URL B 是否同源 原因
http://example.com/a http://example.com/b ✅ 是 协议+域名+端口一致
http://example.com https://example.com ❌ 否 协议不同(http vs https)
http://example.com http://api.example.com ❌ 否 域名不同(子域也算不同)
http://example.com:80 http://example.com:8080 ❌ 否 端口不同

⚠️ 注意:跨域是浏览器限制,不是服务器限制!

你的请求其实已经发到了服务器,服务器也返回了响应,但浏览器拦截了响应,不给前端 JS 使用。


二、为什么要有跨域限制?

想象一下:

  • 你登录了银行网站 bank.com,Cookie 中存有身份凭证;
  • 此时你又打开了一个恶意网站 evil.com
  • 如果 evil.com 能随意向 bank.com 发起 AJAX 请求,就能以你的身份转账!

同源策略正是为了防止这类“CSRF”攻击而设计的。


三、CORS:跨域资源共享(Cross-Origin Resource Sharing)

CORS 是 W3C 制定的标准,允许服务器声明“我信任哪些来源的跨域请求”

🔄 工作流程(由浏览器自动完成)

  1. 前端发起跨域 AJAX 请求(如 fetch('http://api.example.com/data'));
  2. 浏览器检测到跨域,自动在请求头中添加 Origin: http://localhost:3000
  3. 服务器收到请求,检查 Origin 是否在白名单中;
  4. 如果允许,服务器在响应头中加入:
Access-Control-Allow-Origin: http://localhost:3000
  1. 浏览器收到响应,验证 Access-Control-Allow-Origin 是否匹配当前源;
  2. 匹配 → 放行数据给 JS;不匹配 → 抛出 CORS 错误。

✅ 整个过程对开发者透明,代码写法与同源请求完全一致。


四、CORS 的两种请求类型

1. 简单请求(Simple Request)

满足以下条件即为简单请求:

  • 方法为 GETPOSTHEAD
  • 请求头只包含:
  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type(仅限 application/x-www-form-urlencodedmultipart/form-datatext/plain

✅ 特点:只发一次请求,浏览器自动加 Origin 头。


2. 预检请求(Preflight Request)

如果不满足简单请求条件(如使用 PUTDELETE,或 Content-Type: application/json),浏览器会先发一个 OPTIONS 请求 进行“预检”。

示例流程:

// 1. 浏览器先发 OPTIONS 预检
OPTIONS /api/user HTTP/1.1
Origin: http://localhost:3000
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
// 2. 服务器响应预检
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400  // 预检结果缓存 24 小时
// 3. 预检通过,浏览器再发真实 PUT 请求
PUT /api/user ...

💡 预检是为了确保服务器“知道并允许”这种复杂请求,避免意外暴露接口。


五、后端如何正确配置 CORS?

Spring Boot 示例(最常用)

@Configuration
public class CorsConfig {
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOriginPatterns(Arrays.asList("http://localhost:*", "https://yourdomain.com"));
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setAllowCredentials(true); // 允许携带 Cookie
        config.setMaxAge(3600L); // 预检缓存 1 小时
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

关键配置说明:

配置项 作用
allowedOriginPatterns 允许的源(支持通配符,但 * 不能与 credentials=true 共用)
allowedHeaders 允许的请求头
allowedMethods 允许的 HTTP 方法
allowCredentials 是否允许携带 Cookie(设为 true 时,allowedOrigin 不能为 *
maxAge 预检结果缓存时间,减少 OPTIONS 请求

六、常见误区

误区 正确理解
“后端没开 CORS,所以请求发不出去” ❌ 请求已发出,只是浏览器拦截了响应
“用 Nginx 代理就不用管 CORS” ✅ 正确!反向代理可将前后端变为同源
“CORS 是为了防止黑客攻击” ⚠️ 不完全对,主要是防止用户浏览器被滥用
“JSONP 可以替代 CORS” ⚠️ JSONP 仅支持 GET,且有安全风险,已淘汰

七、总结

  • 跨域是浏览器的安全策略,不是服务器问题
  • CORS 是标准解决方案,需服务器配合
  • 简单请求直接发,复杂请求先预检(OPTIONS)
  • 生产环境应明确指定允许的源,避免 * 滥用
  • 开发阶段可用代理(如 Vue/React devServer proxy)绕过跨域

🔑 记住:

“前端负责发起请求,后端负责授权跨域。”

只要前后端协作配置好 CORS,跨域问题迎刃而解!


掌握 CORS,你就不再害怕“跨域错误”,也能更安全地构建现代 Web 应用。


相关文章
|
1月前
|
人工智能 网络协议 Java
一文带你玩转 WebSocket 全链路可观测
在 AI 实时交互爆发的时代,WebSocket 成为核心协议。但其双向、长连接、流式传输特性,让传统链路追踪频频失效。阿里云 LoongSuite 基于 OpenTelemetry 标准,结合探针增强与自定义扩展,首次实现 WebSocket 全链路可观测,支持 Span 粒度控制、上下文透传、异步衔接与关键性能指标采集。
389 43
|
13天前
|
安全 IDE 开发工具
Python类型注解:让代码更清晰可维护
Python类型注解:让代码更清晰可维护
190 144
|
14天前
|
前端开发 JavaScript 算法
前端面试(React框架一)
React 是一个用于构建用户界面的 JavaScript 库,采用虚拟 DOM 提升渲染效率,支持组件化开发与服务端渲染,具有良好的性能优化机制和丰富的生命周期管理。
75 13
|
26天前
|
SQL 监控 安全
常见网络攻击类型详解:从原理到防御
本文系统介绍8种常见网络攻击类型,包括恶意软件、网络钓鱼、中间人攻击、DDoS、SQL注入等,剖析其原理与防御策略,助力提升个人与企业网络安全防护能力。
欧拉筛(最优的方法,对于找质数,细节讲解)
欧拉筛(最优的方法,对于找质数,细节讲解)
385 0
|
26天前
|
人工智能 开发框架 机器人
宝塔部署AstrBot及Napcat防踩坑教程
本教程详述了在宝塔面板11上,通过Docker容器部署AstrBot与Napcat,实现QQ机器人接入AI的全过程。内容涵盖环境搭建、关键配置(如容器网络互通、WebSocket连接及平台适配器设置)等。
宝塔部署AstrBot及Napcat防踩坑教程
|
9天前
|
人工智能 运维 搜索推荐
杭州速车携手蚂蚁百宝箱,快速抢滩文旅AI新市场
杭州速车科技依托蚂蚁百宝箱,打造“福小厝”等9个文旅智能体,实现从技术服务商向“AI+场景”转型。通过低代码平台快速交付,覆盖导览、打卡、营销等场景,服务超10万用户,助力景区提升体验与消费转化。
101 11
|
17天前
|
机器学习/深度学习 人工智能 安全
构建AI智能体:八十六、大模型的指令微调与人类对齐:从知识渊博到善解人意
本文探讨了大模型从知识储备到实用助手的进化过程。首先分析了原始预训练模型存在的问题:擅长文本补全但缺乏指令理解能力,可能生成有害或无关内容。然后详细介绍了指令微调技术,通过高质量(指令-输出)数据集教会模型理解并执行翻译、总结、情感分析等任务。进一步阐述了人类对齐技术,包括基于人类反馈的强化学习(RLHF)的三个关键步骤,使模型输出不仅符合指令,更符合人类价值观。最后展示了Qwen模型微调实践,包括代码实现和效果对比。整个过程将AI从知识库转变为既强大又安全可靠的智能助手。
166 19
|
16天前
|
存储 人工智能 弹性计算
玄晶引擎AI数字化转型技术方案:基于阿里云生态的服务业民企降本增效实践
玄晶引擎深度融合阿里云生态,针对服务业民企“轻资产、重运营”痛点,构建以知识库为底座、AI智能力体为核心的云原生数字化转型方案,实现精准获客、智能运营与盈利重构,助力企业降本增效、拓展业务边界。
103 13
|
24天前
|
机器学习/深度学习 人工智能 算法
技术人视角:传统产品经理如何系统性转型AI产品经理
AI时代重塑产品格局,AI产品经理需兼具技术理解、业务洞察与用户体验。本文系统梳理从认知升级到实战落地的转型路径,助力传统PM或技术人掌握AI产品方法论,避开常见误区,逐步成长为驾驭智能的“系统架构师”。
448 13

热门文章

最新文章