前端安全之CORS跨域资源共享详解
字数 1725 2025-11-07 22:15:37

前端安全之CORS跨域资源共享详解

一、CORS是什么?
CORS(Cross-Origin Resource Sharing)是一种W3C标准,允许浏览器向跨域服务器发送XMLHttpRequest请求或Fetch请求,克服了同源策略的限制。它的核心是通过HTTP头部字段协商跨域权限

二、为什么需要CORS?

  1. 同源策略限制:浏览器默认禁止跨域请求,但实际开发中前端经常需要访问不同域的API。
  2. 早期方案的缺陷:JSONP只支持GET请求,且缺乏错误处理;代理服务器会增加架构复杂度。
  3. CORS的优势:支持所有HTTP方法,安全性可控(服务端配置权限)。

三、CORS的两种请求类型

  1. 简单请求(Simple Request)

    • 条件(同时满足):
      • 方法为GET、POST、HEAD之一;
      • 头部字段仅限允许的安全字段(如Accept、Content-Language、Content-Type等);
      • Content-Type为application/x-www-form-urlencodedmultipart/form-datatext/plain
    • 流程:
      1. 浏览器直接发送跨域请求,并在请求头自动添加Origin: https://a.com
      2. 服务器返回响应头需包含Access-Control-Allow-Origin: https://a.com(或*允许任意域);
      3. 浏览器检查响应头,若匹配则允许获取数据,否则拦截响应。
  2. 预检请求(Preflight Request)

    • 触发条件(满足任一):
      • 方法为PUT、DELETE等非简单方法;
      • 包含自定义头部(如Authorization);
      • Content-Type为application/json
    • 流程:
      1. 浏览器先发送OPTIONS请求(预检请求),头部包含:
        Origin: https://a.com  
        Access-Control-Request-Method: PUT  
        Access-Control-Request-Headers: Content-Type,Authorization  
        
      2. 服务器响应预检请求,需返回以下头部:
        Access-Control-Allow-Origin: https://a.com  
        Access-Control-Allow-Methods: GET,POST,PUT  
        Access-Control-Allow-Headers: Content-Type,Authorization  
        Access-Control-Max-Age: 86400  // 缓存预检结果时间(秒)  
        
      3. 预检通过后,浏览器才发送真实请求,后续同简单请求流程。

四、关键HTTP头部字段详解

字段名 作用 示例
Origin 声明请求的源 Origin: https://a.com
Access-Control-Allow-Origin 服务器允许的源 *https://a.com
Access-Control-Allow-Methods 允许的HTTP方法 GET,POST,PUT
Access-Control-Allow-Headers 允许的自定义头部 Content-Type,Authorization
Access-Control-Allow-Credentials 是否允许发送Cookie true(需配合前端设置withCredentials
Access-Control-Expose-Headers 允许前端访问的响应头 X-Custom-Header

五、带凭证的请求
默认情况下,CORS请求不发送Cookie。若需携带凭证:

  1. 前端设置:
    fetch(url, {  
      credentials: 'include'  // 或same-origin  
    });  
    
  2. 服务端响应头需满足:
    • Access-Control-Allow-Origin不能为*,必须指定具体域名;
    • 设置Access-Control-Allow-Credentials: true

六、常见问题与解决方案

  1. 预检请求失败:检查服务器是否正确响应OPTIONS请求,并返回允许的Methods和Headers。
  2. 响应被拦截:确保Access-Control-Allow-Origin与Origin一致,且不带凭证时不能用通配符*
  3. 缓存优化:通过Access-Control-Max-Age减少预检请求频率。

七、实际配置示例(Node.js)

// 中间件设置CORS头  
app.use((req, res, next) => {  
  res.setHeader('Access-Control-Allow-Origin', 'https://a.com');  
  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT');  
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');  
  res.setHeader('Access-Control-Allow-Credentials', 'true');  
  // 预检请求直接返回200  
  if (req.method === 'OPTIONS') {  
    return res.sendStatus(200);  
  }  
  next();  
});  

八、总结
CORS通过服务端声明权限、浏览器验证的机制,在安全前提下实现了灵活跨域。开发时需注意区分简单/预检请求,正确设置头部字段,并谨慎处理带凭证的请求。

前端安全之CORS跨域资源共享详解 一、CORS是什么? CORS(Cross-Origin Resource Sharing)是一种W3C标准,允许浏览器向跨域服务器发送XMLHttpRequest请求或Fetch请求,克服了同源策略的限制。它的核心是 通过HTTP头部字段协商跨域权限 。 二、为什么需要CORS? 同源策略限制 :浏览器默认禁止跨域请求,但实际开发中前端经常需要访问不同域的API。 早期方案的缺陷 :JSONP只支持GET请求,且缺乏错误处理;代理服务器会增加架构复杂度。 CORS的优势 :支持所有HTTP方法,安全性可控(服务端配置权限)。 三、CORS的两种请求类型 简单请求 (Simple Request) 条件(同时满足): 方法为GET、POST、HEAD之一; 头部字段仅限允许的安全字段(如Accept、Content-Language、Content-Type等); Content-Type为 application/x-www-form-urlencoded 、 multipart/form-data 或 text/plain 。 流程: 浏览器直接发送跨域请求,并在请求头自动添加 Origin: https://a.com ; 服务器返回响应头需包含 Access-Control-Allow-Origin: https://a.com (或 * 允许任意域); 浏览器检查响应头,若匹配则允许获取数据,否则拦截响应。 预检请求 (Preflight Request) 触发条件(满足任一): 方法为PUT、DELETE等非简单方法; 包含自定义头部(如 Authorization ); Content-Type为 application/json 。 流程: 浏览器先发送OPTIONS请求(预检请求),头部包含: 服务器响应预检请求,需返回以下头部: 预检通过后,浏览器才发送真实请求,后续同简单请求流程。 四、关键HTTP头部字段详解 | 字段名 | 作用 | 示例 | |--------|------|------| | Origin | 声明请求的源 | Origin: https://a.com | | Access-Control-Allow-Origin | 服务器允许的源 | * 或 https://a.com | | Access-Control-Allow-Methods | 允许的HTTP方法 | GET,POST,PUT | | Access-Control-Allow-Headers | 允许的自定义头部 | Content-Type,Authorization | | Access-Control-Allow-Credentials | 是否允许发送Cookie | true (需配合前端设置 withCredentials ) | | Access-Control-Expose-Headers | 允许前端访问的响应头 | X-Custom-Header | 五、带凭证的请求 默认情况下,CORS请求不发送Cookie。若需携带凭证: 前端设置: 服务端响应头需满足: Access-Control-Allow-Origin 不能为 * ,必须指定具体域名; 设置 Access-Control-Allow-Credentials: true 。 六、常见问题与解决方案 预检请求失败 :检查服务器是否正确响应OPTIONS请求,并返回允许的Methods和Headers。 响应被拦截 :确保 Access-Control-Allow-Origin 与Origin一致,且不带凭证时不能用通配符 * 。 缓存优化 :通过 Access-Control-Max-Age 减少预检请求频率。 七、实际配置示例(Node.js) 八、总结 CORS通过服务端声明权限、浏览器验证的机制,在安全前提下实现了灵活跨域。开发时需注意区分简单/预检请求,正确设置头部字段,并谨慎处理带凭证的请求。