HTTP 完全指南(最终篇):CORS 跨域资源共享深度详解

发布时间:2026/6/7 17:31:41

HTTP 完全指南(最终篇):CORS 跨域资源共享深度详解 引言前端开发中最让人头疼的报错之一Access to XMLHttpRequest at http://api.example.com/userfrom origin http://www.example.com has been blocked by CORS policy:No Access-Control-Allow-Origin header is present on the requested resource.这就是跨域问题。很多开发者的第一反应是后端加个Access-Control-Allow-Origin: *就好了但为什么加这个就能解决什么时候该用*什么时候不该用带 Cookie 的跨域请求怎么处理本文将彻底讲透 CORS 的原理、分类和解决方案。第一部分同源策略一、什么是同源两个 URL 同源必须满足三个条件完全相同条件URL1URL2是否同源协议http://https://❌ 协议不同域名www.a.comapi.a.com❌ 子域名不同端口:80:8080❌ 端口不同全部相同http://a.com:80/ahttp://a.com:80/b✅ 同源同源策略限制的是Cookie、LocalStorage 的读取DOM 的访问AJAX 请求的发送不受同源策略限制的script src...加载 JSimg src...加载图片link href...加载 CSSa链接跳转表单提交这就是为什么 JSONP 能跨域——它利用了script标签不受同源策略限制的漏洞。第二部分CORS 的分类浏览器把跨域请求分为两类简单请求和非简单请求。一、简单请求的三个条件必须同时满足1. 请求方法是以下三种之一GETHEADPOST2. 只包含以下请求头不能有自定义头AcceptAccept-LanguageContent-LanguageContent-Type仅限三种值3. Content-Type 只能是text/plainmultipart/form-dataapplication/x-www-form-urlencoded任何不满足以上条件的就是非简单请求。比如PUT、DELETE、PATCH 方法自定义请求头如Authorization、X-Custom-HeaderContent-Type 是application/json二、简单请求的流程核心头请求头Origin: http://www.example.com响应头Access-Control-Allow-Origin: http://www.example.com三、非简单请求预检请求预检请求相关的头头请求含义Access-Control-Request-Method告知真实请求的方法Access-Control-Request-Headers告知真实请求的自定义头头响应含义Access-Control-Allow-Origin允许的源Access-Control-Allow-Methods允许的方法Access-Control-Allow-Headers允许的请求头Access-Control-Max-Age预检缓存时间秒时间内不发第二次预检第三部分带 Cookie 的跨域请求默认情况下跨域请求不携带 Cookie。一、前端设置// 原生 XHR const xhr new XMLHttpRequest(); xhr.withCredentials true; // 关键 // Fetch fetch(http://api.example.com/user, { credentials: include // 关键 });二、后端设置响应头 Access-Control-Allow-Origin: http://www.example.com ← 不能用 * Access-Control-Allow-Credentials: true ← 必须两条硬规则Access-Control-Allow-Origin不能是*必须是具体的源必须加Access-Control-Allow-Credentials: true第四部分完整 CORS 响应头速查响应头作用示例Access-Control-Allow-Origin允许的源http://www.example.com或*Access-Control-Allow-Credentials允许携带 CookietrueAccess-Control-Allow-Methods允许的 HTTP 方法GET, POST, PUT, DELETEAccess-Control-Allow-Headers允许的请求头Authorization, Content-TypeAccess-Control-Expose-Headers允许 JS 读取的响应头X-Total-CountAccess-Control-Max-Age预检缓存时间8640024小时第五部分常见跨域解决方案对比方案原理优点缺点CORS服务器加响应头标准方案功能完整需要后端配合JSONPscript标签不受跨域限制兼容老浏览器只支持 GET反向代理同域下转发请求彻底避开跨域需要运维配置postMessageHTML5 跨文档通信iframe 间通信需双方配合WebSocket不受同源策略限制双向通信需要服务器支持JSONP 示例script function handleResponse(data) { console.log(data); } /script script srchttp://api.example.com/user?callbackhandleResponse/script// 服务器返回 handleResponse({name: 张三, age: 20});JSONP 已过时新项目统一用 CORS。反向代理开发环境常用// vite.config.js export default { server: { proxy: { /api: { target: http://api.example.com, changeOrigin: true } } } };前端请求/api/user→ 开发服务器转发到http://api.example.com/api/user→ 同源无跨域问题。第六部分面试题1. Q什么是同源策略A浏览器安全机制。两个 URL 的协议、域名、端口必须完全相同才算同源。同源策略限制不同源之间的 Cookie 读取、DOM 访问、AJAX 请求。2. Q简单请求和非简单请求的区别A简单请求GET/POST/HEAD 特定 Content-Type直接发送浏览器自动带 Origin 头。非简单请求PUT/DELETE、自定义头、application/json先发 OPTIONS 预检请求服务器允许后才发真实请求。3. Q跨域带 Cookie 需要什么配置A前端设置withCredentials: true后端设置Access-Control-Allow-Origin为具体源不能用*Access-Control-Allow-Credentials: trueCookie 本身需要SameSiteNone; Secure。4. Q为什么跨域请求的响应被拦截了但请求实际已发出A浏览器的同源策略只拦截JS 读取响应不拦截请求的发送。服务器确实收到了请求并处理了。这是防止恶意网站读取用户数据但不阻止数据提交。5. QCORS 和 JSONP 选哪个ACORS。JSONP 只支持 GET、有 XSS 风险、已过时。新项目统一用 CORS需要兼容老 IE 时才考虑 JSONP。总结一、CORS 核心流程二、关键响应头Access-Control-Allow-Origin: http://www.example.com Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Authorization, Content-Type Access-Control-Max-Age: 86400三、一句话记忆同源策略限制跨域 AJAXCORS 通过服务器返回Access-Control-Allow-Origin等响应头来授权跨域访问。简单请求直接带 Origin非简单请求先发 OPTIONS 预检。带 Cookie 需要前端开withCredentials 后端指定具体 Origin 并开Credentials。

相关新闻