麦式参考 MickerBook Reference

CORS

CORS

也常被叫作:跨域跨域问题跨域限制cors报错跨域配置

你可能会这么说

「浏览器规定网页只能访问自己域名下的接口;要跨域名拿数据,得对方服务器在响应里明确点头允许。」

CORS CORS

浏览器的一道安全规则:网页默认只能请求自己域名下的接口,跨域名取数要对方服务器显式允许。

你的网站是一个小区,浏览器是门卫,接口在别的小区。门卫的规矩:业主(同源)随便进出;访客(跨域)要先由被访者(服务器)提前登记放行,没登记就拦在门口。关键认知:这个规矩是浏览器定的,不是服务器定的——所以「关掉 CORS」在浏览器里做不到,只能让服务器配置允许谁进来。

同源 = 协议 + 域名 + 端口三者完全一致:https://a.com 和 https://b.com 不同源,http 和 https 之间也不同源。跨域请求分两类:简单请求直接发;带自定义头、非 GET/POST 等「复杂请求」会先发一个 OPTIONS 预检,问服务器「这个跨域请求你允许吗」。服务器要在响应里返回 Access-Control-Allow-Origin 等头表示允许。最常见的报错原文是 No 'Access-Control-Allow-Origin' header is present。解决办法在后端(加响应头),或者开发环境用代理转发绕开——但代理只在开发环境有效,上线后依然直连,所以不是根治。

前后端分开部署后(前端域名 a.com、接口域名 api.b.com),跨域报错几乎是必踩的坑。AI 最常见的糊弄是「我加了 CORS 配置」却没生效:加错了地方、没重启、允许的域名写错。验收方法很硬:浏览器 F12 → 网络面板,找到被拦截的请求,看它的响应头里有没有 Access-Control-Allow-Origin、值是不是你的域名。这是能亲眼看到的事实,不需要懂代码。

长什么样 真实可交互,不是截图

浏览器控制台的跨域报错:
Access to fetch at 'https://api.b.com/users' from origin
'https://a.com' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present

后端响应里要加的头(允许 a.com 访问):
Access-Control-Allow-Origin: https://a.com
a.com 页面请求 api.b.com浏览器拦下:无允许头后端加头后放行

注意加的是 https://a.com 而不是 *:允许任意域名等于对所有网站开放这个接口,带登录凭证时还会直接失效。

拆开看,里面有这几块

  1. 1
    同源 Same-origin

    协议 + 域名 + 端口三者完全一致才叫同源。http 和 https 不同源,端口不同也不同源。

  2. 2
    跨域请求 Cross-origin request

    页面请求了非同源的接口。浏览器默认允许发出去,但不允许你读到响应,除非服务器点头。

  3. 3
    响应头 CORS headers

    服务器在响应里加的头,如 Access-Control-Allow-Origin,声明允许哪个源访问。

  4. 4
    预检请求 Preflight (OPTIONS)

    复杂请求先发一个 OPTIONS 问服务器「允许吗」。后端没处理 OPTIONS,复杂请求照样被拦。

常见的有哪几种

后端加响应头Server CORS headers

在接口的响应里加 Access-Control-Allow-Origin,指向你的具体域名。正解。

用在:前后端分域部署、要上线

开发代理Dev proxy

开发环境把请求转发到后端,浏览器以为在请求同源。

用在:本地开发联调,上线前要换掉

同源部署Same-origin deploy

前端和后端放同一个域名下(如 api 子路径),从根上避开跨域。

用在:自己能控制部署结构时

容易搞混?这样区分

CORS 网络不通 Network failure

CORS 报错说明请求已经发出、服务器也回了,只是浏览器拒绝让你读响应;网络不通是请求根本没到服务器。看网络面板里请求的「已发送 / 已接收」状态能区分:CORS 拦截时请求状态是已完成,只是响应不可见。

看 网络不通
CORS 鉴权失败 Auth failure

CORS 是「浏览器允不允许你读这个响应」,鉴权是「服务器认不认你是谁」。跨域请求即使 CORS 放行了,服务器照样会因为你没带凭证返回 401。两个问题会叠加,别混在一起排。

看 鉴权失败

什么时候用得上

前端连线上接口

本地页面把接口地址从 localhost 改成线上域名,立刻报 CORS——开发时靠代理,上线要后端加头。

带登录凭证

跨域请求带 cookie 时,后端除了 Allow-Origin 要写具体域名,还要配置凭证模式,否则浏览器照样拦。

多域名

一个接口服务多个前端域名(根域、www、CDN 域名),每个都要在允许列表里,漏一个就报错。

你可以这样跟 AI 说

直接复制下面这段,把【】里的换成你的情况。它比一句「帮我加个 X」多说清楚了:改哪里、不许动啥、做完交什么。

【任务】解决 [页面] 请求 [api 地址] 时的跨域报错
【范围】只改 [后端服务名] 的 CORS 配置,不改前端业务代码
【目标】页面在 [线上域名,如 https://a.com] 下能正常读取该接口的响应
【边界】不允许用 * 允许所有域名(尤其接口带登录凭证时);不要用开发代理冒充线上解决;不要为了绕 CORS 把接口改成 JSONP 或把密钥写进前端
【交付】
  1. 改的是哪个文件、加了哪几行,把配置原文贴出来
  2. 重启服务后,我在网络面板里看到被拦的请求响应头里有 Access-Control-Allow-Origin,值是我的域名
  3. 用无痕窗口从线上域名实测一次,把请求成功或失败的网络面板信息贴给我
  4. 如果还有第二个域名要访问,说明怎么加,而不是只解决当前这个
【提醒】改完必须重启生效,否则等于没改

「用无痕窗口从线上域名实测」是关键:开发代理、浏览器缓存都会让本地看起来好了,只有线上域名 + 无痕窗口才能证明真实环境。

它说「做好了」,你怎么自己验

这是本站的重头戏。AI 最会的不是写代码,是说「已完成」。这一条,它通常最多做到「运行时」这层:真的跑起来了,能在本机看到结果。

要亲眼看到这些,才算数

  • 页面接口指向线上域名后,打开 F12 → 网络面板,找到那个请求,亲眼看报错信息和它的响应头。
  • 请求成功时,确认响应头 Access-Control-Allow-Origin 的值就是你的域名,不是 *(尤其你要带登录凭证时)。
  • 用无痕窗口再试一次,排除缓存和旧代码干扰。
  • 如果 AI 说「加了配置」,让它重启服务,你刷新后重新看报错是否消失——配置要生效才算数。
  • 让 AI 说出它加配置的具体文件位置和原文,而不是一句「已经加了」。

它常这么糊弄你

  • 「CORS 已解决」——但只是开发环境用代理绕过了,部署到线上直连依然报错。确认线上域名直连能通。
  • 后端允许了 *(任意域名),声称「解决了」——等于把接口开放给所有网站,带 cookie 时还会失效。
  • 把跨域报错说成「浏览器问题 / 网络问题」,让你别管——报错原文和响应头就摆在网络面板里。
  • 前端加了个自定义头(比如 Authorization),把简单请求变成预检请求,后端没处理 OPTIONS,报错反而变多。

CORS 能验到「运行时」层:在浏览器里真实发起跨域请求,看响应头、看报错消失。但线上还有多域名(根域 vs www、CDN 域名)、带凭证模式这些组合,完整确认要到生产环境。

考考你 选一个你觉得对的

前端在 a.com,接口在 api.b.com,跨域报错。AI 说「CORS 已解决,你刷新试试」。你第一反应是?