请解释 HTTP 中的 CORS(跨域资源共享),如何设置 CORS策略?

1. 基础概念(用程序员能听懂的人话)

CORS(跨域资源共享)是浏览器用来控制"跨域请求"是否被允许的机制。比如你的前端在http://localhost:3000,后端在http://api.yourdomain.com,这时候浏览器会阻止前端直接调用后端接口,除非后端明确声明允许跨域。

**为什么需要它?**​ 浏览器的同源策略默认禁止跨域请求,防止恶意网站窃取数据。而CORS就像一张通行证,告诉浏览器:"这个跨域请求是我允许的,放行吧!"


2. CORS核心流程(配代码示例)
2.1 简单请求(Simple Request)

满足以下条件时浏览器直接发送请求:

  1. 方法为GET/POST/HEAD

  2. 仅包含AcceptContent-Type(仅限text/plainmultipart/form-dataapplication/x-www-form-urlencoded)等简单Header

    // 前端代码(浏览器会自动处理)
    fetch('http://api.com/data') // 不同域的请求

    // 后端响应必须包含(以Node.js为例)
    app.get('/data', (req, res) => {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000') // 允许的源
    res.send(data)
    })

2.2 预检请求(Preflight Request)

当请求包含自定义Header、Content-Type: application/json等复杂情况时,浏览器会先发OPTIONS请求探路:

复制代码
// 前端发送复杂请求
fetch('http://api.com/data', {
  method: 'PUT',
  headers: { 'X-Custom-Header': 'value' }
})

// 后端需要处理OPTIONS请求(Express中间件示例)
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE') // 允许的方法
  res.header('Access-Control-Allow-Headers', 'X-Custom-Header') // 允许的Header
  res.header('Access-Control-Max-Age', 86400) // 缓存预检结果24小时
  
  if (req.method === 'OPTIONS') {
    return res.sendStatus(200) // 直接响应预检请求
  }
  next()
})

3. 日常开发建议(避坑指南)
3.1 生产环境安全配置
复制代码
// 错误示范:允许所有域(存在安全隐患)
res.setHeader('Access-Control-Allow-Origin', '*')

// 正确做法:动态白名单
const allowedOrigins = ['https://prod.com', 'https://staging.com']
const origin = req.headers.origin
if (allowedOrigins.includes(origin)) {
  res.setHeader('Access-Control-Allow-Origin', origin)
}
3.2 携带Cookie等凭证
复制代码
// 前端需要设置credentials
fetch('http://api.com/data', {
  credentials: 'include' // 携带Cookie
})

// 后端需要配置
res.header('Access-Control-Allow-Credentials', 'true')
// 注意:此时Access-Control-Allow-Origin不能为*
3.3 处理Vary头部

避免CDN缓存错误响应:

复制代码
res.header('Vary', 'Origin') // 告诉缓存服务器根据Origin区分响应

4. 常见问题排查技巧
4.1 浏览器控制台报错:
  • No 'Access-Control-Allow-Origin' header → 检查后端是否返回该Header
  • Response to preflight... → 检查OPTIONS请求处理逻辑
  • Credentials not supported → 检查是否同时设置credentials:includeAllow-Credentials
4.2 开发环境代理方案(Vite示例):
复制代码
// vite.config.js
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true // 关键配置
      }
    }
  }
}

5. 高级注意事项
5.1 非简单请求的性能影响

预检请求会增加一次HTTP往返,对延迟敏感型接口:

  • 使用Access-Control-Max-Age减少预检次数
  • 尽量将复杂请求改造为简单请求
5.2 防御CSRF攻击

即使配置了CORS,仍需防范CSRF:

复制代码
// 后端校验请求头(推荐使用库如csurf)
app.use(csurf({ cookie: true }))
5.3 监控异常请求
复制代码
// 记录非法Origin请求
app.use((req, res, next) => {
  const origin = req.headers.origin
  if (origin && !allowedOrigins.includes(origin)) {
    console.warn(`非法跨域请求: ${origin}`)
  }
  next()
})

总结 Checklist

  1. 明确区分开发/生产环境的CORS配置
  2. 敏感操作必须指定具体Origin而非通配符
  3. 带凭证的请求要特殊处理
  4. 长期缓存预检结果提升性能
  5. 结合日志监控异常跨域请求

理解CORS不仅是为了通过面试,更是构建安全可靠的Web应用的必备技能。建议通过Chrome DevTools的Network面板实际观察请求/响应头,加深对机制的理解。

相关推荐
春风解人意4 小时前
从零开始学习嵌入式P32----网络基础之TCP
c语言·网络·学习·tcp/ip
云絮.5 小时前
网络原理---- 网络层,数据链路层,应用层
网络
Johny_Zhao7 小时前
网络安全等级保护测评实施方案
linux·网络·人工智能·网络安全·信息安全·云计算·等保测评·系统运维·itsm
虹科网络安全8 小时前
使用艾体宝 IOTA 10 CORE+ 监控企业网络中的 AI 流量
网络·人工智能
醉颜凉8 小时前
网络安全必学:粘性MAC地址(Sticky MAC)原理与应用全解析
运维·服务器·网络·安全·web安全
广州灵眸科技有限公司10 小时前
从手动三步到上电即连:4G模组systemd开机自连方案
linux·运维·服务器·开发语言·网络·人工智能·php
埃科光电10 小时前
16K万兆网口彩色线阵相机:四倍带宽 高速真彩检测新方案
网络·图像处理·数码相机·计算机视觉·制造·相机
运维全栈笔记11 小时前
Windows 安装 WSL2 并运行 Ubuntu 24.04 指南
linux·网络·windows·ubuntu
qq_4523962311 小时前
第十篇:《eBPF 可观测性:零侵扰的深度内核追踪》
服务器·网络·php
迪康Defender12 小时前
政企内网终端安全建设:资产‑管控‑防护‑审计闭环能力拆解
运维·网络·安全·web安全·终端安全管理