一句话:CORS(Cross-Origin Resource Sharing,跨域资源共享)是浏览器的一套安全规则——它决定"当前页面里的 JS,能不能把另一个域名下的接口返回的数据读走"。
关键点:被拦下的不是请求,是你读数据的那只手
很多人遇到跨域报错,第一反应是"后端挂了"或"请求没发出去"。恰恰相反:请求通常发出去了,后端也处理了,日志里甚至能看到记录,只是浏览器在把响应交给你的 JS 之前,把它扣下了。
打个比方。你让助理去隔壁公司拿一份文件。助理真的去了,对方也真的把文件递给了他。但你们公司有个规矩:外来文件必须盖过对方公章才能带进办公室。助理拿着文件站在门口,保安一看没章,直接把文件没收——于是你桌上什么都没有,你的"拿文件"这个动作失败得干干净净。隔壁公司的前台记录里却清清楚楚写着"某某来过"。浏览器就是那个保安,后端日志就是隔壁公司的来访登记。
为什么会有这条规矩
想象没有 CORS 的世界:你登录了网银,浏览器里存着网银的 Cookie。这时你点开一个恶意网页,页面里的 JS 悄悄向网银发请求——浏览器会自动带上 Cookie,请求合法通过。恶意页面虽然读不到返回内容(同源策略挡住了),但已经足以完成一次转账。同源策略(Same-Origin Policy)是最底层的护栏,CORS 则是护栏上开的一扇"凭票通行"的门。
"同源"怎么算
协议、域名、端口三者全一样才算同源。http 与 https 不同源,a.com 与 api.a.com 不同源,:3000 与 :8000 不同源。所以本地前端跑在 3000 端口、后端跑在 8000 端口,天天跨域,非常正常。
那些响应头都是干什么的
| 响应头 | 作用 | 记忆点 |
|---|---|---|
Access-Control-Allow-Origin | 允许哪些来源读取 | 写 * 或具体域名 |
Access-Control-Allow-Credentials | 是否允许带 Cookie | 为 true 时不能用 * |
Access-Control-Allow-Methods | 允许哪些方法 | 预检请求里用 |
Access-Control-Allow-Headers | 允许哪些自定义头 | 加了自定义头就会触发预检 |
预检请求(Preflight)
当你发了 PUT、DELETE,或者带了自定义请求头,浏览器会先用 OPTIONS 探一次路,问后端"我能不能这么干"。探路通过了,真正的请求才发。所以后端路由如果只写了 POST 忘了 OPTIONS,就会看到预检失败——这是新手最常见的坑。
和几个相邻概念的区别
- 同源策略:默认禁止,是规则本身;CORS 是规则允许的例外。
- 代理(Proxy):绕过跨域的另一条路。请求由你自己的服务器转发,浏览器认为它没跨域。开发环境常用。
- CSRF(跨站请求伪造):跨域限制要防的正是这类攻击,两者常一起出现。
对从业者的实际意义
给 AI 应用写前端时,调用第三方模型 API 几乎一定撞上 CORS:浏览器直连被拦,日志还查不出问题。这时候基本只有两种正经解法——把请求挪到自己的后端中转,或者确认对方接口明确支持浏览器直连。排查时记住一句话:先看浏览器控制台,再看后端日志。控制台告诉你"谁被拦了",后端日志只能告诉你"请求到过这里"。具体某个接口允许哪些来源、允许带不带 Cookie,以该服务官方文档为准。
