返回知识库

数据与服务 · 网络与接口

跨域资源共享CORS

CORS 由浏览器决定网页能否读取跨来源响应。服务端已处理不等于脚本可读;带凭据时必须允许明确 Origin,不能用通配 * 代替。

账号页为什么拿不到已经返回的 200?

模拟一次带 Cookie 的跨域账号请求:先发起请求,再修正同一行响应头。注意三块物件的顺序——API 已处理,并不自动等于网页脚本可以读到响应。

ACCOUNT SCREEN · /me等待读取资料

账号页已经带上登录 Cookie。现在发一次请求,先看 API 是否处理,再看浏览器会不会把同一份响应交给页面。

浏览器请求GET /v1/me

Origin: https://app.example.com
Cookie: sid=lin_42

凭据请求:浏览器要求明确许可。
API 服务端尚未收到请求

点击下方按钮后,服务端会处理这次请求。

Access-Control-Allow-Origin: *Access-Control-Allow-Credentials: true
网页脚本资料区还在等待响应

还没有请求,账号页没有可显示的资料。

第 0 步:尚未发送。预期是 API 会返回 200,但网页仍可能没有资料。

把刚才看到的规则命名

CORS 是浏览器对跨来源响应的读取许可;服务端用响应头回答,前端不能把它关掉。

1 · Origin 是问题

浏览器自动带上网页来源;服务端应按白名单回显允许的来源,而不是相信前端自行填写。

2 · 200 与可读取是两件事

刚才 API 的 200 说明服务端已处理;CORS 不通过时,浏览器仍把响应正文挡在网页脚本外。

3 · 凭据不能配通配

credentials: "include" 时,Access-Control-Allow-Origin: * 无效;还要有 Access-Control-Allow-Credentials: true。

4 · JSON POST 先问预检

非简单方法或请求头会先发 OPTIONS;服务端还要允许方法与请求头,否则实际 POST 根本不会发出。

什么时候看它,最短怎么修

浏览器报 CORS、但 curl 或 Postman 能通时,先区分“服务端是否处理”与“网页是否被允许读取”。

适用信号
  • 控制台出现 blocked by CORS policy 或缺少 Access-Control-Allow-Origin,却能在服务端日志看到请求。
  • 网页与 API 的协议、主机或端口任一不同;同源请求和服务器到服务器调用不走这道浏览器规则。
最短排查路径
  1. 在浏览器 Network 里确认是“没有响应”还是“有响应、脚本不可读”。
  2. 服务端按允许来源回 Access-Control-Allow-Origin,动态回显时加 Vary: Origin。
  3. 带 Cookie 同时回 Access-Control-Allow-Credentials: true;JSON POST 再检查 OPTIONS 的方法和请求头。

不要用前端插件、no-cors 或随手放开 * 掩盖问题:它们不会让带凭据的响应安全地变得可读。

同一账号请求,只改一行就反转

两边都带同一个 Cookie、同一个 Origin、同一个 200;唯一差别是服务端允许了谁读取。

正例 · 精确许可网页可显示资料

Access-Control-Allow-Origin: https://app.example.com 加 Access-Control-Allow-Credentials: true。浏览器把响应交给账号页。

反例 · 通配来源网页仍拿不到资料

Access-Control-Allow-Origin: * 配合凭据。API 可能仍已返回 200,但浏览器拒绝暴露正文;改为明确白名单。

快速自测

JSON POST 的 OPTIONS 响应漏掉 Access-Control-Allow-Headers: Content-Type 时,浏览器会怎样?

继续查证

术语的技术定义和行为以这些一手或权威资料为准。

下一步学

和本知识点经常一起出现的概念。