什么是CORS?如何正确配置?

以下是关于CORS(跨域资源共享)的完整解析及配置指南,结合资料中的关键信息进行系统化阐述:


一、CORS的定义与作用

1. 基本概念
  • CORS(Cross-Origin Resource Sharing) 是W3C标准的安全机制,允许浏览器绕过同源策略(Same-Origin Policy, SOP),安全地访问不同源的资源(如API、图片、字体等)。
  • 同源策略(SOP) 是浏览器的核心安全机制,默认阻止跨域请求(协议、域名、端口任一不同即视为跨域)。
2. 解决的问题
  • 现代Web应用常需跨域访问资源(如前端调用第三方API、CDN共享资源),但SOP会阻止此类请求。CORS通过HTTP头部协商机制,在保持安全的前提下解除限制。
  • 典型应用场景
    • HTML5文件拖拽上传至不同源存储服务(如OBS)。
    • 跨域加载外部网页、样式表或Web字体。
    • 多站点共享同一资源(如图片库)。

二、CORS的工作原理

1. 关键参与者
  • 浏览器:自动处理CORS流程(发送预检请求、验证响应头)。
  • 服务器:通过响应头声明允许的跨域规则。
2. 请求分类与流程
请求类型触发条件流程步骤
简单请求方法为GET/POST/HEAD,头部为Accept、Content-Type等简单字段1. 浏览器直接发送请求
2. 检查响应头Access-Control-Allow-Origin是否匹配
预检请求方法为PUT/DELETE或含自定义头部(如Authorization)1. 浏览器先发OPTIONS请求(预检)
2. 服务器返回允许的规则
3. 通过后发送实际请求
3. 核心HTTP头部
  • 请求头
    • Origin:声明请求来源(如[https://example.com](https://example.com))。
    • Access-Control-Request-Method:声明实际请求方法(预检请求携带)。
    • Access-Control-Request-Headers:声明自定义头部(预检请求携带)。
  • 响应头
    • Access-Control-Allow-Origin:允许的源(如[https://example.com](https://example.com)*)。
    • Access-Control-Allow-Methods:允许的HTTP方法(如GET,POST)。
    • Access-Control-Allow-Headers:允许的自定义头部。
    • Access-Control-Allow-Credentials:是否允许携带凭据(如Cookies)。
    • Access-Control-Max-Age:预检结果缓存时间(秒)。

示例预检请求/响应

OPTIONS /api/data HTTP/1.1
Origin: [https://yuanjava.com](https://yuanjava.com)
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: [https://yuanjava.com](https://yuanjava.com)
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600

三、CORS的正确配置方法

1. 服务器端配置(关键步骤)

需在资源服务器配置响应头,以下是主流方案:

  • 通用配置原则

    • 明确允许的源(避免滥用*)。
    • 按需开放方法(GET/POST等)和头部。
    • 若需凭据(Cookies),设置Access-Control-Allow-Credentials: true禁止使用*作为源
  • 配置示例

    • Apache服务器(修改.htaccess):
Header set Access-Control-Allow-Origin "https://your-domain.com"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
Header set Access-Control-Allow-Credentials "true"

     Nginx服务器(修改配置文件):

    add_header Access-Control-Allow-Origin "https://your-domain.com";
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'Content-Type, Authorization';
    add_header Access-Control-Allow-Credentials 'true';
    

    后端框架示例

    • Spring Boot(Java):
    @Configuration
    public class CorsConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                .allowedOrigins("https://your-domain.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowCredentials(true)
                .maxAge(3600);
        }
    }
    

    Express(Node.js):

    const cors = require('cors');
    app.use(cors({
        origin: 'https://your-domain.com',
        methods: ['GET', 'POST'],
        credentials: true
    }));
    

    GoFrame(Golang):

    // boot.yaml
    gf:
      interceptors:
        cors:
          enabled: true
          allowOrigins: "https://your-domain.com"
          allowMethods: "GET,POST"
    
    2. 客户端注意事项

    若请求需携带凭据(如Cookies),前端需显式设置:

    fetch('https://api.com/data', {
      credentials: 'include' // 或 xhr.withCredentials = true;
    });
    
    • 否则浏览器会拒绝跨域凭据请求。


    四、常见错误与解决方案

    错误现象原因分析解决方案
    No 'Access-Control-Allow-Origin' header is present服务器未返回Access-Control-Allow-Origin响应头检查服务器配置,确保该头部存在且值匹配请求源
    Access-Control-Allow-Origin cannot be '*' when using credentials凭据模式下不允许源为通配符*指定具体源(如[https://example.com](https://example.com))并设置Access-Control-Allow-Credentials: true
    CORS preflight channel did not succeed预检请求(OPTIONS)未正确处理(如返回非200状态码)确保服务器正确响应OPTIONS请求,返回200及CORS头部
    Method [PUT] not allowed in Access-Control-Allow-Methods实际请求方法不在服务器允许的方法列表中Access-Control-Allow-Methods中添加缺失方法(如PUT)

    调试建议
    使用浏览器开发者工具查看Network选项卡,分析预检请求(OPTIONS)和实际请求的请求头/响应头,定位缺失或错误的CORS头部。


    五、进阶实践与安全建议

    1. 动态源管理
      • 若允许多个源,可编程检查Origin请求头,动态设置Access-Control-Allow-Origin(需避免漏洞)。
    2. 预检缓存优化
      • 设置Access-Control-Max-Age减少OPTIONS请求频率(如3600秒)。
    3. 安全风险规避
      • 避免Access-Control-Allow-Origin: *:尤其在涉及敏感数据或凭据时。
      • 限制HTTP方法:仅开放必要方法(如禁止DELETE)。
      • 验证来源域名:防止未授权站点利用CORS。

    六、总结

    CORS是平衡安全性与灵活性的关键技术,其核心在于服务器通过HTTP头部声明跨域规则,由浏览器强制执行。正确配置需关注:

    1. 区分简单请求与预检请求的处理逻辑。
    2. 精准设置Access-Control-Allow-*系列头部。
    3. 避免凭据模式下的通配符滥用。
    4. 结合具体服务器环境(Apache/Nginx/框架)实现配置。

    通过理解机制、规范配置和善用调试工具,可高效解决跨域问题。

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    破碎的天堂鸟

    你的鼓励将是我创作的最大动力

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值