Web安全之同源策略的例外:CORS跨域资源共享详解
字数 914 2025-11-21 02:38:40

Web安全之同源策略的例外:CORS跨域资源共享详解

1. 问题背景与定义
当浏览器从https://a.com向https://b.com/api发起XMLHttpRequest请求时,控制台会出现错误:"Blocked by CORS policy"。这是由浏览器的同源策略引起的安全限制。CORS(跨域资源共享)是W3C标准,允许服务器声明哪些外部源有权访问资源,是当前最主流的跨域解决方案。

2. 核心概念解析

  • 简单请求:满足以下所有条件的请求
    • 方法为GET/HEAD/POST
    • Content-Type为text/plain、multipart/form-data、application/x-www-form-urlencoded
    • 无自定义头部(如Authorization)
  • 预检请求:不满足简单请求条件的请求(如PUT/DELETE方法或自定义头部)
  • 请求凭证:Cookies、HTTP认证等敏感信息

3. 简单请求的CORS流程

  1. 浏览器自动添加Origin头:Origin: https://a.com
  2. 服务器响应需包含:
    Access-Control-Allow-Origin: https://a.com  // 或通配符*
    Access-Control-Expose-Headers: X-Custom-Header  // 允许前端访问的额外头部
    
  3. 浏览器检查响应头,若Origin值在Allow-Origin列表中,则解除拦截

4. 预检请求的完整流程

  1. 浏览器先发送OPTIONS请求(预检请求):
    OPTIONS /api/data HTTP/1.1
    Origin: https://a.com
    Access-Control-Request-Method: PUT
    Access-Control-Request-Headers: X-Custom-Header
    
  2. 服务器响应预检:
    Access-Control-Allow-Origin: https://a.com
    Access-Control-Allow-Methods: GET,PUT,POST
    Access-Control-Allow-Headers: X-Custom-Header
    Access-Control-Max-Age: 86400  // 预检结果缓存时间(秒)
    
  3. 通过预检后,浏览器才发送实际请求

5. 带凭证的请求处理
当请求需要携带Cookies时:

  1. 前端设置:xhr.withCredentials = true
  2. 服务器响应需设置:
    Access-Control-Allow-Origin: https://a.com  // 不能为*
    Access-Control-Allow-Credentials: true
    

6. 服务端配置示例(Node.js/Express)

app.use((req, res, next) => {
  const allowedOrigins = ['https://a.com', 'https://b.com'];
  const origin = req.headers.origin;
  
  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }
  res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  res.setHeader('Access-Control-Max-Age', '86400');
  
  // 立即返回预检请求
  if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }
  next();
});

7. 安全注意事项

  • 避免使用Access-Control-Allow-Origin: *与凭证混用
  • 严格校验Origin头防止伪造(参考Origin头不可伪造特性)
  • 敏感操作应额外实施CSRF保护
  • 合理设置Max-Age平衡性能与安全

8. 常见问题排查

  • 预检请求失败:检查Allow-Methods/Headers配置
  • 凭证未被发送:确认withCredentials设置和服务器Allow-Credentials
  • 缓存问题:预检结果缓存期间修改配置可能导致异常
Web安全之同源策略的例外:CORS跨域资源共享详解 1. 问题背景与定义 当浏览器从https://a.com向https://b.com/api发起XMLHttpRequest请求时,控制台会出现错误:"Blocked by CORS policy"。这是由浏览器的同源策略引起的安全限制。CORS(跨域资源共享)是W3C标准,允许服务器声明哪些外部源有权访问资源,是当前最主流的跨域解决方案。 2. 核心概念解析 简单请求 :满足以下所有条件的请求 方法为GET/HEAD/POST Content-Type为text/plain、multipart/form-data、application/x-www-form-urlencoded 无自定义头部(如Authorization) 预检请求 :不满足简单请求条件的请求(如PUT/DELETE方法或自定义头部) 请求凭证 :Cookies、HTTP认证等敏感信息 3. 简单请求的CORS流程 浏览器自动添加Origin头: Origin: https://a.com 服务器响应需包含: 浏览器检查响应头,若Origin值在Allow-Origin列表中,则解除拦截 4. 预检请求的完整流程 浏览器先发送OPTIONS请求(预检请求): 服务器响应预检: 通过预检后,浏览器才发送实际请求 5. 带凭证的请求处理 当请求需要携带Cookies时: 前端设置: xhr.withCredentials = true 服务器响应需设置: 6. 服务端配置示例(Node.js/Express) 7. 安全注意事项 避免使用 Access-Control-Allow-Origin: * 与凭证混用 严格校验Origin头防止伪造(参考Origin头不可伪造特性) 敏感操作应额外实施CSRF保护 合理设置Max-Age平衡性能与安全 8. 常见问题排查 预检请求失败:检查Allow-Methods/Headers配置 凭证未被发送:确认withCredentials设置和服务器Allow-Credentials 缓存问题:预检结果缓存期间修改配置可能导致异常