跨域(CORS)是什么?一文读懂前端最头疼的跨域报错
跨域(CORS)是什么?一文读懂前端最头疼的跨域报错
你本地跑得好好的前端页面,一调后端接口就弹出 Access-Control-Allow-Origin 相关的红色报错,接口返回 200 却拿不到数据。这是几乎每个前端新手都会撞上的墙。跨域(CORS)的核心答案先给出来:它是浏览器出于安全考虑,默认禁止网页去请求「和自己来源不同」的接口的一种保护机制;报错不是后端挂了,而是浏览器把响应拦了下来。今天这篇文章,编程狮就用最通俗的比喻把它讲透。
本文基于现代浏览器与 HTTP 协议验证,覆盖同源策略的原理、CORS 的响应头机制、常见跨域报错的解法,以及开发环境最省事的代理方案。看完你不但能看懂那条红色报错在说什么,还能知道该找谁、怎么改。
一、一句话说清什么是跨域
跨域指的是:你当前网页的「来源」和你要请求的「目标地址」不一致。这里的来源由三部分锁定——协议、域名、端口,三者有一个不同,浏览器就判定为跨域。比如你的页面在 http://localhost:3000,却去请求 https://api.example.com,协议不同、域名不同,于是跨域。
把来源想象成门牌号:协议是小区(http/https),域名是楼栋(example.com),端口是房间号(3000/8080)。只要有一项对不上,浏览器就认为「你去了别人家」,于是启动保护。同源策略是这套保护的总规则,CORS 则是在规则里开的「通行证」。
举个最直接的例子:http://a.com:3000 和 https://a.com:3000 跨域(协议不同);http://a.com 和 http://www.a.com 跨域(域名不同,www 也算不同主机);http://a.com:3000 和 http://a.com:8080 也跨域(端口不同)。只有三者完全一致,浏览器才当作同源放行。很多人排查半天,最后发现只是端口写错了一位。
💡 小提示:很多人误以为跨域是后端接口挂了。其实接口往往正常返回了,只是浏览器看完响应头发现「没有放行许可」,才把数据扣下不交给你的 JS。
二、同源策略:浏览器为什么要拦你
同源策略(Same-Origin Policy)是浏览器从一开始就定下的铁律:一个网页里的脚本,只能读取和它同源的资源。它的初衷是防止恶意网站偷偷拿着你的登录态去攻击别的站点——比如你登录了银行,又打开了一个坏网站,坏网站若能动用你的银行接口,后果不堪设想。
所以浏览器不是故意和你作对,而是在替你挡风险。前端报错里最让人头秃的,往往就是这种「请求发出去了、后端也回了、可我就是拿不到」的跨域拦截。理解了它保护的是什么,你就不会再把它当成玄学。
同源策略管得很宽:Cookie、DOM、接口数据都在它的防护范围内。平时你感觉不到它,是因为大多数页面只和自己的同源后端打交道;一旦前后端分离、域名不同,它立刻就跳出来。
一个常见的连带影响是 Cookie:同源策略下,脚本只能读取自己来源下的 Cookie,跨域请求的 Cookie 默认也不会自动带上。所以即使接口通了,如果你的登录态是靠 Cookie 传递的,跨域场景还得额外处理凭证,这也是为什么单纯加了 CORS 头有时还不够。
三、CORS 到底是什么:预检与响应头
CORS(跨源资源共享)是官方给出的「合法放行」方案:后端在响应里带上特定的 HTTP 头,告诉浏览器「这个接口允许谁跨域访问」。最关键的头是 Access-Control-Allow-Origin。
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://your-site.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
上面这段响应头的意思是:只允许 https://your-site.com 这个来源跨域访问,且支持指定的方法和请求头。浏览器看到这一行,就放心把数据交给前端。关于 HTTP 响应头和状态码的完整机制,HTTP 教程 里讲得更系统。
还有一类「预检请求」(preflight):当你的请求带自定义头、或用 PUT/DELETE 这类非简单方法时,浏览器会先悄悄发一个 OPTIONS 请求去问「我能不能跨域」,后端同意了才发真正的请求。很多人没处理 OPTIONS,于是卡在预检这一步。
补充一个容易踩的点:如果你的请求需要携带 Cookie 等凭证,前端要设 fetch 的 credentials: 'include',后端还要额外返回 Access-Control-Allow-Credentials: true,且此时 Allow-Origin 不能再用 *,必须写明确的来源。凭证和通配符二者不可兼得,这是 CORS 里最常被忽略的一条。
四、常见跨域报错与对应解法
前端报错虽然千奇百怪,落到解法上基本是三条路,按场景选:
场景
报错特征
解法
后端是你自己的
No 'Access-Control-Allow-Origin'
后端加响应头放行
只在本机联调
本地 3000 调 8080 被拦
开发服务器配代理
老系统不支持头
改不了后端
用 JSONP 或网关中转
顺带说下表格里的 JSONP:它是 CORS 普及前的老办法,利用